![]() | ![]() | ![]() | 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 1000
Ver 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...) |