![]() | ![]() | ![]() | Exercícios práticos (muitos...) |
Ir directamente para exercício: 1 5 10 15 20 25 30 final
Exercícios
//-- Retorna o num. de divisores de n (entre 1 e n).
int ndiv(int n){
int i,s;
for(i=1;i<n;i++){
if(n%i=0) s++;
return(s);
}
As armas e os 7 barõesdeve ser transformado em
AS ARMAS E OS 7 BARES
Notas
#include <stdio.h>
main(){
int ch=getchar();
while(ch!=EOF){
if(ch>='a' && ch <='z')
ch += ...
if(ch>=... && ch <=...)
putchar(ch);
ch=getchar();
}
}
a.out < ...
//-- inteiro aleatório >=a e <=b
int aleat(int a, int b){
return(a+(rand()%(b-a+1)));
}
Notas.uma solução deste problema:
main(){
int i,d1,d2;
double num=0;
srand(getpid());
for(i=0;i<LANCS;i++){
int d1=aleat(1,6);
int d2=aleat(1,6);
if(d1+d2>=4)
num++;
}
printf("Prob = %8.4f\n",num/LANCS);
}
-> Compare o valor obtido com a previsão "teórica".
void mostra(int a[],int n){
int i;
for(i=0;i<m;i++)
printf("%3d",v[i]);
printf("\n");
}
main(){
int v[]={8,2,6,18,4}, n=5;
troca(v,n,0);
mostra(v,n);
troca(v,n,1);
mostra(v,n);
}
Neste programa falta definir a função
void troca(int v[],int m,int i)
que deve ter como efeito trocar v[i] com v[k] onde k
é o índice que contém o menor dos valores
void mostra(int a[],int n){
int i;
for(i=0;i<m;i++)
printf("%3d",v[i]);
printf("\n");
}
main(){
int v[]={8,2,6,18,4}, n=5;
mostra(v,n);
ordena(v,n,1);
mostra(v,n);
}
Neste programa falta definir a função
void ordena(int v[],int m)
que deve ter como efeito ordenar o vector v[i] com m
elementos por ordem crescente utilizando a seguinte observação: <PAL1>@<PAL2> <PAL1> e <PAL1> são sequências máximas de 1 ou mais caracteres
dos seguintes tipos:A,B,...,Z,a,b,...z,1,2,...,9,-,_,,. Exemplos:x2yz@com.com, ataca-te@laden.pt.
Notas: (i) Utilize apenas getchar e putchar como funções de entrada e saída. (ii) Quando está a formar um eventual endereço, vá guardando os caracteres correspondentes num vector, (iii) Como sempre, utilize a divisão apropriada do seu programa em funções com vista a o estruturar!
9,2 -> 2, 118,10 -> 9, 8,10 -> 16
O seu programa deve incluir uma função
"int somad(int n)"
que retorna a soma dos divisores próprios de n.
Escreva um programa que lê n e imprime o primeiro valor positivo de i não superior a 1000 tal que f(i)=n ou -1 se tal i não existe.
printf("%3.3f",m);
Exemplo: 4 1 5 3 2, resultado: 2.
int pertence(int x,int v[], int n)
main(){
int a,
v[]={8,5,2,12,25,9,10,81,4,22}, nv=10;
do{
printf("Valor (negativo para acabar)? ");
scanf("%d",&a);
printf("%s\n",pertence(a,v,nv)?"SIM":"NAO");
} while(a>=0);
}
int diferenca(int x[], int m, int y[], int n, int z[], int *p)Como se sabe a diferença entre os conjuntos A e B é o conjunto dos elementos de A que não pertencem a B.
#define MAX 100
main(){
int v[]={2,4,6,8,10,12,14,16}, nv=8,
w[]={2,8,9,3}, nw=4,
z[MAX], nz,
i;
diferenca(v,nv,w,nw,z,&nz);
for(i=0;i<nz;i++)
printf("%3d",z[i]);
}
"3 ba\bax*s!" a resposta é 3 (correspondente à
palavra "bax".
void roda(char s[],int n)" que tem como
efeito "rodar no alfabeto" todas as letras de s (maiúsculas ou minúsculas) de n posições. Assim, se n=2, o string "ac Z" é transformado
em "ce B".
Nota. Pode usar o seguinte programa para testar a função que escreveu.
main(){
int n;
char v[MAX];
strcpy(v,"as Nuvens");
printf("Chave? ");
scanf("%d",&n);
roda(v,n);
printf("%s\n",v);
roda(v,-n);
printf("%s\n",v);
}
void estica(char s[])" que, no
"string s, introduz um espaço após cada caracter."as nuvens" fica transformado em"a s n u v e n s "
Supõe-se que em s[] existe espaço suficiente para efectuar esta
operação.
Nota. Pode usar o seguinte programa para testar a função que escreveu.
main(){
char v[MAX];
strcpy(v,"as nuvens");
estica(v);
printf("<%s>\n",v);
}
[2.1, 1.9, 2.6, 1.8, 1.9, 1.2, 2.0]
float media(float v[], int n)" que dá como
resultado a média dos n valores do vector v[].
float dp(float v[], int n)" que dá como
resultado a raíz quadrada de((v[0]-m)^2 + (v[1]-m)^2 +...+ (v[n-1]-m)^2)/(n-1)
void retira(float v[], int *n)"3*dp(v,n) (ver a alínea anterior).v[].
Nota. Pode usar o seguinte programa para testar as funções que escreveu.
void imprime(float v[], int n){
int i;
printf("\n[");
for(i=0;i<n;i++)
printf("%4.2f ",v[i]);
printf("]\n");
}
...
main(){
float v[]={2.1, 1.9, 2.6, 1.8, 1.9, 1.2, 2.0};
int nv=7;
imprime(v,nv);
printf("m=%4.2f, dp=%4.2f\n",media(v,nv),dp(v,nv));
retira(v,&nv);
imprime(v,nv);
}
$ conta fich printf("%20s tem %8d caracteres\n",arg[i],nc);
Modifique o seu programa por forma a funcionar com um número qualquer de
ficheiros, escrevendo para cada um o nome e o número de caracteres.
Experimente com conta *.
void trocapar(int v[],int n)v[] = [2,3,4,10,15] deve ficarv[] = [3,2,10,4,15].
main(){
int v[]={2,3,4,10,15}, nv=5,i;
trocapar(v,nv);
for(i=0;i<nv;i++)
printf("%3d",v[i]);
}
void unico(char s[]) "abbb++bb*****!" deve ficar "ab+b*!"
main(){
char v[MAX];
strcpy(v,"as nuvens");
unico(v);
printf("<%s>\n",v);
}
#include <stdio.h>
#define MAX 100
int t[MAX];
void imprime(int m){
int i;
for(i=0;i<m;i++)
printf("%2d",t[i]);
printf("\n");
}
/*-- escreve em t[] a partir do indice ti
a decomposicao nao decrescente de n
em inteiros nao excedendo max. */
void somas(int n,int max,int ti){
int i;
if(n==0){
imprime(ti); /*- Escrever uma soma! */
return;
}
for(i=1;i<=max && i<=n;i++){
t[ti]=i; /*- uma parcela... */
somas(n-i,i,ti+1); /*- somas do resto... */
}
}
main(){
int n;
scanf("%d",&n);
somas(n,n,0);
}
Teste o programa e explique o seu funcionamento.
void baralha(int v[],int n)
main(){
int i, n, a[MAX];
srand(getpid());
scanf("%d",&n);
baralha(a,n);
for(i=0;i<n;i++)
printf("%3d",a[i]);
printf("\n");
}
#define MAX 52
#define MAO 13
main(){
int i, n, a[MAX];
char *nome[]={
"Ap","Rp","Dp","Jp","2p","3p","4p","5p","6p","7p","8p","9p","10p",
"Ac","Rc","Dc","Jc","2c","3c","4c","5c","6c","7c","8c","9c","10c",
"Ae","Re","De","Je","2e","3e","4e","5e","6e","7e","8e","9e","10e",
"Ao","Ro","Do","Jo","2o","3o","4o","5o","6o","7o","8o","9o","10o"};
srand(getpid());
baralha(a,MAX);
for(i=0;i<MAO;i++)
printf("%5s",???]);
printf("\n");
}
Exemplo:
? 3 1 2 3 1 3 2 2 1 3 2 3 1 3 2 1 3 1 2
Sugestão: Um método baseia-se na seguinte observação: suponhamos que para i=1,2,···,n o elemento v[i] é inicializado com i (não estamos a usar v[0]). Colocamos no primeiro elemento do vector sucessivamente 1, 2,..., n e geramos recursivamente todas as permutações possíveis dos elementos seguintes (índices 2 a n ).
1 2 3 1 3 2 - - 2 1 3 2 3 1 (1o elem. trocado com o segundo) - - 3 2 1 3 1 2 (1o elem. trocado com o último ) - -
A função
void perm(int i,int n,int v[])
tem como objectivo gerar e imprimir todas as permutações dos elementos do vector, supondo-se que os elementos anteriores ao elemento i estão já fixados. Quando acabar por ser chamada com i>n (nas chamadas recursivas o valor de i vai aumentano), o vector contém uma permutação e é impresso.
Um esquema do respectivo algoritmo pode ser:
void perm(int i,int n,int v[]){
Se i>n {escreve o vector; return;}
para j=i, i+1,...,n:
troca v[i] <-> v[j]
//-- E, recursivamente, gera as possiveis
//-- permutacoes da parte da frente:
perm(i+1,n,v);
//-- repoe o valor de início
troca v[i] <-> v[j]
}
Teste o método indicado para n=2 e para n=3.
Organização: O seu programa poderá estar organizado em 3 funções:
#define MAX 100
void escreve(int v[], int n){
int i;
for(i=1;i<=n;i++)
printf("%3d",v[i]);
printf("\n");
}
void perm(int i,int n,int v[]){
...
main(){
int i, v[MAX], n;
scanf("%d",&n);
for(i=1;i<=n;i++)
v[i]=i;
perm(1,n,v);
}
$ calc 12 x 1000Ver o exemplo dado nas aulas teóricas relativo à multiplicação de 2 inteiros (na secção parâmetros a partir da "shell".
0 1 2 3 4
-------------
0 | 1 2 3 1 5 |
1 | 1 2 8 0 6 |
2 | 1 2 2 4 3 |
3 | 2 2 4 1 4*|
4 | 5 4 8 1 2 |
temos vários máximos locais; um deles (marcado com *), na linha 3,
coluna 4, tem o valor 4.
Escreva uma função
int maxr(int lin,int col,int nl, int nc)que determina se o elemento da linha lin, coluna col da matriz (a matriz é uma variável global) é um máximo local. A matriz tem nl linhas e nc colunas.
Um programa completo com o objectivo de determinar todos os máximos locais pode então ter a seguinte estrutura:
int v[][5]={{1,2,3,1,5},
{1,2,8,0,6},
{1,2,2,4,3},
{2,2,4,1,4},
{5,4,8,1,2}},
nl=5, nc=5;
int maxl(int lin,int col,int nl, int nc){
..............
int main(){
int i,j;
for(i=0;i<nl;i++)
for(j=0;j<nc;j++)
if(maxl(i,j,nl,nc))
printf("Maximo local de %3d em linha=%3d, col=%3d\n",
v[i][j],i,j);
}
? 2 2 (pergunta a linha e a coluna)
0 1 2 3 4 5 6 7 8 9
-------------------- (indica o número de vizinhos)
0 | |
1 | |
2 | 4 |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
--------------------
? 7 4
0 1 2 3 4 5 6 7 8 9 (pergunta a linha e a coluna)
--------------------
0 | | (indica o número de vizinhos)
1 | |
2 | 4 |
3 | |
4 | |
5 | |
6 | |
7 | 3 |
8 | |
9 | |
--------------------
? 1 5 (pergunta a linha e a coluna)
(Era uma mina, acaba o programa)
BUUUM!
0 1 2 3 4 5 6 7 8 9
--------------------
0 | * * * *|
1 | * * * * |
2 | * * * |
3 | * * * * * *|
4 | * * * * * * * *|
5 | * * * |
6 | * * * * *|
7 | * * * * *|
8 | * * * *|
9 | * * * * * *|
--------------------
Sugere-se a utilização de 2 variáveis bidimensionais, uma com as minas geradas
aleatoriamente e a outra com a situação que é mostrada ao utilizador
(com a indicação do número de vizinhos).
O programa principal pode ter a seguinte estrutura:
main(){
char tab[MAX][MAX], //-- "tabuleiro"
out[MAX][MAX]; //-- o que mostra
int nl=10, nc=10, //-- num de linhas e de colunas
linha,col,i,j; //-- escolhidas pelo utilizador
double prob=0.5; //-- probabilidade de ser mina
srand(getpid());
gera(tab,nl,nc,prob); //-- Geração aleatória
espacos(out,nl,nc); //-- Coloca espaços em out[][]
do{ //-- De cada vez:
mostra(out,nl,nc); //-- Mostra a situação actual
scanf("%d %d",&linha,&col); //-- Lê linha e coluna
if(tab[linha][col]==' ') //-- Testa se bomba, se não:
out[linha][col]='0'+vizinhos(linha,col,tab,nl,nc);
} while(tab[linha][col]==' ');
printf("BUUUM!\n\n"); //-- Bomba, acabou,
mostra(tab,nl,nc); //-- Mostra o tabuleiro
}
Há pois que implementar as seguintes funções:
void mostra(char t[][MAX],int nl,int nc): mostra a situação ou - no final - o tabuleiro int random_int(int a, int b): ver um exercício anterior void gera(char t[][MAX],int nl,int nc,double prob): gera aleatoriamente a posição das minas void espacos(char t[][MAX],int nl,int nc): preenche uma matriz t[][] de espaços ' ' int vizinhos(int lin,int col,char tab[][MAX],int nl,int nc): retorna o número de bombas na vizinhança de tab[lin][col]-------------------
Assim, se as bombas estão nas posições indicadas
0 1 2 3 4
------------------
0 | 0 X 0 0 0 |
1 | 0 0 0 0 0 |
2 | 0 0 0 0 0 |
3 | 0 X X 0 0 |
4 | X 0 0 0 0 |
------------------
e o utilizador selecciona na primeira jogada a linha 0, coluna 4,
deve aparecer:
0 1 2 3 4
------------------
0 | : : |
1 | : : |
2 | : |
3 | : |
4 | : |
------------------
onde o caracter ":" significa 0.
Poderá utilizar no seu programa a seguinte estruturação.
//-- numeros maximos de linhas e colunas
#define NCOLS 30
#define NLINS 40
// inteiro aleatório em [a...b]
int random_int(int a, int b){
return(a+(rand()%(b-a+1)));
}
/*-- Gera aleatoriamente em t[][] minas
com a probabilidade p (inteiro entre 1 e 10,
correspondendo a probabilidades de 0.1 a 0.9)
e inicializa d[][] --*/
void gera(int prob,int t[][NCOLS],int d[][NCOLS],int nl,int nc){
............
//-- Mostra o tabuleiro ao utilizador
void mostra(int d[][NCOLS],int nl,int nc){
............
//-- Retorna o número de bombas vizinhas de t[i][j]
int vizinhos(int a,int b,int t[][NCOLS],int nl,int nc){
............
/*-- Para cada célula com 0 vizinhos: calcula vizinhos
(iterativamente) */
void novos(int t[][NCOLS],int d[][NCOLS],int nl,int nc){
............
//-- Perdeu: mostra o tabuleiro (com as bombas)
void bum(int t[][NCOLS],int d[][NCOLS],int nl,int nc){
/*-- Aceita um inteiro x entre min e max;
Dá a mensagem mess se for dado um fora dos limites */
void enter(char *mess,int *x,int min,int max){
-------------------------------------------------------------
main(){
int tabu[NLINS][NCOLS], //-- estado das celulas
displ[NLINS][NCOLS], //-- quadro mostrado
nlin, //-- numero real de linhas
ncol; //-- numero real de colunas
int prob,i,j,jogando=1;
enter("N. de linhas? ", &nlin,1,NLINS-1);
enter("N. de colunas? ",&ncol,1,NCOLS-1);
enter("Probabilidade (0..10, inteiro)? ",&prob,1,9);
srand(getpid());
gera(prob,tabu,displ,nlin,ncol);
while(jogando){
mostra(displ,nlin,ncol);
enter("lin= ? ",&i,0,nlin-1);
enter("col= ? ",&j,0,ncol-1);
if(tabu[i][j]){
bum(tabu,displ,nlin,ncol);
mostra(displ,nlin,ncol);
jogando=0;
}
else
if(displ[i][j]==NADA){
displ[i][j]='0'+vizinhos(i,j,tabu,nlin,ncol);
if(displ[i][j]=='0')
displ[i][j]=ZERO;
novos(tabu,displ,nlin,ncol);
}
}
}
1| #define MAXF 20
2| #define MAX 100
|
3| main(){
4| char *p[MAXF]={"as armas e os baroes",
5| "vamos passear!",
6| "andam 3 nuvens",
7| "lado de cima",
8| ""}, s[MAX];
|
9| int i,j,c,nf,minc=0;
|
10| nf=0;
11| while(p[nf][0]!=0)
12| nf++;
13| minc=strlen(p[0]);
14| for(i=1;i<nf;i++)
15| if((c=strlen(p[i]))<minc)
16| minc=c;
|
17| for(j=0;j<minc;j++){
18| for(i=0;i<nf;i++)
19| s[i]=p[i][j];
20| s[i]=0;
21| printf(" %s\n",s);
22| }
23| }
Exemplo:
Computador (0) ou humano (1)? 1 soma = 0 Jogada? 5 soma = 5 Computador joga 6 soma = 11 Jogada? 6 soma = 17 Computador joga 6 soma = 23 Jogada? 4 soma = 27 Computador joga 3 soma = 30 -- Vitoria do computador!!!
Objectivo: implementar um programa que jogue (bem!) com o utilizador este jogo.
Sugestão Começar por descobrir uma estratégia vitoriosa (se houver hipótese de ganhar). Implementar essa estratégia quando possível - isto é, quando há hipótese de ganhar - ou seleccionar um inteiro aleatório entre 1 e 6 caso contrário.
Sugere-se a divisão conveniente do programa em funções que poderão ser, por exemplo (não é obrigatório) - as seguintes
/*-- retorna um inteiro aleatorio entre a e b (inclusivé)
int aleat(int a, int b)... ver exercício anterior
/*-- Depois de escrever a mensagem m (Exemplos:
"Jogada? ", "Computador (0) ou humano (1)? ")
pede ao utilizador um numero entre a e b,
retornando esse número */
int resposta(char *m,int a,int b)...
/*-- Selecciona uma jogada vitoriosa, se possivel...
soma: valor actual da soma dos números. */
int jogada(int soma)...
//-- main: contém o ciclo principal do jogo
main()...
Exemplo
$ ./a.out < letras.c f[a] = 11.4% f[i] = 11.1% f[e] = 9.7% f[t] = 9.3% f[r] = 9.0% f[f] = 8.0% f[l] = 7.6% f[n] = 6.9% ............ f[b] = 0.0%
Sugere-se o seguinte método para resolver este problema.
Usar um vector f[] para contar o número de ocorrências de cada letra e
um vector let[] com as letras; por exemplo, no início f[0]=...=f[25]=0, let[0]='a',...,let[25]='z'
f[c-'a']++
(f[i],let[i])
![]() | ![]() | ![]() | Exercícios práticos (muitos...) |