Professional Documents
Culture Documents
MARCO AURLIO CAVASIN MELARA PAULO FRANCISCO FERREIRA DE ASSIS RODRIGO SCARANTE CORDEIRO
Curitiba 2007
MARCO AURLIO CAVASIN MELARA PAULO FRANCISCO FERREIRA DE ASSIS RODRIGO SCARANTE CORDEIRO
Trabalho em Equipe para desenvolvimento de algoritmo e cdigo em linguagem C para soluo do problema e do Ratinho Esfomeado com o objetivo de obteno de crditos na disciplina de Estrutura de Dados do Curso de Bacharelado em Sistemas da Informao da FESP. Orientador: prof.: RAZER ANTHOM NIZER ROJAS MONTAO
Curitiba 2007
O Ratinho Esfomeado
Objetivo: Dado um labirinto (matriz n x m) e paredes, a posio do ratinho, a posio do queijo, e as posies de sadas, desenvolva um programa que calcula p caminho que o ratinho deve fazer para, o mais rpido possvel, encontrar o queijo e vazar dali rapidinho. O programa deve detectar se o ratinho no chega nunca no queijo ou se no consegue sair do labirinto ou as duas coisas, para que o ratinho no perca tempo. Pelo enunciado, o arquivo a ser lido dever respeitar o procolo definido, contendo na primeira linha o tamanho da matriz , a segunda linha a posio do ratinho, a terceira a posio do queijo, a quarta a quantidade de sadas e a posio de cada sada. Devemos ter ateno s referncias matriz se iniciam no zero. Trabalhos em duas frentes, sendo a primeiro o caminho do do rato para o queijo e a outra do queijo para a sada mais prxima. Simbologia: R (ratinho), Q (queijo), # (parede), falta de parede siginida sada, "." o ponto significa o caminho a ser percorrido. Importante salientar que o ratinho encontrar o queijo atravs de seu
cheiro, sendo que a medida que o ratinho se aproxima do queijo o cheiro ficar mais forte, na nossa implementao quanto menor o valor referente ao cheiro, mais proximo do queijo . Estratgia: Iniciando-se pelo preenchimento do labirinto a partir do queijo para o rato; Simulando o cheiro do queijo, enumerando entre todos as casas, vazias do labirinto partindo do nmero um, e expandindo-se de forma crescente at encontrar o rato.
Descrio do Algoritmo e definio das Estruturas: Montar um arquivo que dever ser lido mantendo-se o formato definido no enunciado do problema; Na definio do tamanho da matriz denominada funo aloca_matriz com o parmetro nxm; Marcar na matriz j declarada a posio do queijo; Informar para o programa a quantidade de paredes, que permitirao a finalizacao da leitura das paredes: Aps a leitura das paredes (definidos os bloqueios) a prxima informao a ser repassada ao programa ser a quantidade de sadas, e as respectivas posies para cada uma delas. Para o ratinho encontrar o queijo pelo cheiro, deveremos atribuir nmeros crescentes do queijo at o rato; A partir da posio do queijo iniciaremos o preenchimento das posies da matriz com nmeros crescentes, a partir do nmero 1, Verificando sempre se na prxima clula teremos a possibilidade de gravar a informao, determinando a distncia do queijo. Para analisar-mos o melhor caminho do rato para o queijo aps a numerao das celulas com os indices de proximidade, iremos analisar a partir da posio do rato, a numerao em sequencia que determine o caminho, analisando em volta da posico inicial do rato. Para analisar-mos a melhor sada, iremos analisar a partir do Sada para o queijo, os ndices alocados as celulas e realizamos a definio da melhor sada . Cdigo: //************************************************************** //RATO_ESFOMEADO.c // Trabalho de Estrutura de Dados // Valores nos campos das Matrizes : // -1 = Rato (R) // -2 = Queijo (Q) // -3 = Parede (#)
// -4 = Saidas (Sem barreira nos limites ) //**************************************************************** #include <stdio.h> #include <stdlib.h> int **aloca_matriz (int l, int c); int alocar_indices(int lin, int col, int l, int c, int cont, int **matriz); void limpa_matriz (int l, int c, int **matriz); void imprime_matriz(int l, int c, int **matriz); int encontra_caminho(int lin,int col, int num,int **matriz, int **matriz_rato_queijo); int encontra_caminho_saidas(int lin, int col, int **matriz,int **matriz_queijo_saida); int main (void){ int retorno = 0; int cont = 0; int col = 0; int lin = 0; int **matriz; int **matriz_rato_queijo; int **matriz_queijo_saida; int i_linha = 1; int parede=0; int aux_l; int aux_c; int queijo_linha; int queijo_coluna; int rato_linha; int rato_coluna; int p_l; int p_c; int saida=0; int num = 0; char aux_char; FILE *arq; char linha[15]; int temp; arq=fopen("rato.txt","r"); // Abertura do arquivo if(arq == NULL){ perror("ERRO AO ABRIR ARQUIVO"); return 1; }
do{ // inicio a verificao do arquivo de acordo com as posicoes da linhas // discriminada na documentao switch(i_linha){ case 1: // Indica o tamanho matriz fscanf(arq,"%d%*c%d", &aux_l, &aux_c); matriz = aloca_matriz (aux_l,aux_c); matriz_rato_queijo = aloca_matriz (aux_l,aux_c); matriz_queijo_saida = aloca_matriz (aux_l,aux_c); limpa_matriz (aux_l,aux_c, matriz); limpa_matriz (aux_l, aux_c, matriz_rato_queijo ); limpa_matriz (aux_l, aux_c, matriz_queijo_saida ); i_linha++; break; case 2: //Indica a posicao ratinho fscanf(arq,"%d%*c%d", &rato_linha, &rato_coluna); matriz[rato_linha][rato_coluna]=-1; matriz_rato_queijo[rato_linha][rato_coluna]=-1; matriz_queijo_saida[rato_linha][rato_coluna]=-1; i_linha++; fgets(linha,sizeof(linha),arq); break; case 3: //Indica a posicao queijo fscanf(arq,"%d%*c%d", &queijo_linha, &queijo_coluna); matriz[queijo_linha][queijo_coluna]=-2; matriz_rato_queijo[queijo_linha][queijo_coluna]=-2; matriz_queijo_saida[queijo_linha][queijo_coluna]=-2; i_linha++; break; case 4: //Indica a quantidade de paredes fscanf(arq,"%d", &parede); i_linha++; break; default: fscanf(arq,"%d%*c%d", &p_l, &p_c); // comeco a leitura das parades if (i_linha <= parede + 4){ matriz[p_l][p_c]=-3; matriz_rato_queijo[p_l][p_c]=-3; matriz_queijo_saida[p_l][p_c]=-3; i_linha++; break; } if (i_linha == parede + 5){ // quantidade de saida fscanf(arq,"%d", &saida); i_linha++; break;
} if (i_linha <= parede + saida + 5){ // leitura das saida matriz[p_l][p_c]=-4; matriz_rato_queijo[p_l][p_c]=-4; matriz_queijo_saida[p_l][p_c]=-4; i_linha++; break; } break; } }while(!feof(arq)); // Leitura at o final do arquivo ; fclose(arq); // fecho o arquivo // Inicio o preenchimento dos valores na matriz para determinar os caminhos retorno = alocar_indices(queijo_linha,queijo_coluna,1,aux_l,aux_c,matriz); //Inicio a anlise para determinar o menor valor at o queijo num=0; if(rato_linha+1>=0){ if(matriz[rato_linha+1][rato_coluna] > 0){ if(num>0){ if(num > matriz[rato_linha+1][rato_coluna]){ col = rato_coluna; lin = rato_linha + 1; num = matriz[rato_linha+1][rato_coluna]; } } else{ num = matriz[rato_linha+1][rato_coluna]; col = rato_coluna; lin = rato_linha + 1; } } } if(rato_coluna+1>=0){ if(matriz[rato_linha][rato_coluna+1] > 0){ if(num>0){ if(num > matriz[rato_linha][rato_coluna+1]){ col = rato_coluna + 1; lin = rato_linha; num = matriz[rato_linha][rato_coluna+1]; } } else{ col = rato_coluna + 1;
lin = rato_linha; num = matriz[rato_linha][rato_coluna+1]; } } } if(rato_linha-1>=0){ if(matriz[rato_linha-1][rato_coluna] > 0){ if(num>0){ if(num > matriz[rato_linha-1][rato_coluna]){ col = rato_coluna; lin = rato_linha - 1; num = matriz[rato_linha-1][rato_coluna]; } } else{ col = rato_coluna; lin = rato_linha - 1; num = matriz[rato_linha-1][rato_coluna]; } } } if(rato_coluna-1>=0){ if(matriz[rato_linha][rato_coluna-1] > 0){ if(num>0){ if(num > matriz[rato_linha][rato_coluna-1]){ col = rato_coluna - 1; lin = rato_linha; num = matriz[rato_linha][rato_coluna-1]; } } else{ col = rato_coluna - 1; lin = rato_linha; num = matriz[rato_linha][rato_coluna-1]; } } }
// Se a variavel num = 0 , nao teremos caminho para o queijo if( num == 0 ) { printf("\nSEM CAMINHOS PARA O QUEIJO\n"); return(0); }
// Caminho rato -> queijo retorno = encontra_caminho(lin,col,num,matriz,matriz_rato_queijo); // Caminho Saida retorno = encontra_caminho_saidas(aux_l,aux_c,matriz, matriz_queijo_saida); if( retorno == 0 ) { printf("SEM SAIDA\n"); return(0); } imprime_matriz(aux_l, aux_c, matriz); scanf("%d",&temp); printf("\n\n Melhor Caminho para chegar ao queijo\n"); imprime_matriz(aux_l, aux_c, matriz_rato_queijo); scanf("%d",&temp); printf("\n\n Melhor Saida \n"); imprime_matriz(aux_l, aux_c, matriz_queijo_saida); scanf("%d",&temp); return 0; } //************************************************************* //* Funcao aloca_indice: preenche os campos da matriz , //* informando os melhores caminhos //* lin = linha onde esta o queijo //* col = coluna onde esta o quijo //* cont = contador auxiliar //* l = linha auxiliar //* c = coluna auxiliar //* **matriz = endereco incial onde esta alocada a matriz principal; //************************************************************* int alocar_indices(int lin, int col, int cont, int l, int c, int **matriz){ int verificar = 0; // Analise para a movimentacao dos campos em volta , com inicio do queijo, if((col > c-1 || lin > l-1 || col < 0 || lin < 0 || (matriz[lin][col] != 0 && matriz[lin] [col] < cont))&& cont != 1 ){
return 1; }else{ if(cont !=1){ matriz[lin][col] = cont; } cont ++; // Parte Inferior da Matriz verificar += alocar_indices(lin+1,col, cont,l,c,matriz); // Parte Superior da Matriz verificar += alocar_indices(lin-1, col, cont,l,c,matriz); // Parte a Direita da Matriz verificar += alocar_indices(lin, col + 1, cont,l,c,matriz); // Parte a esquerda da Matriz verificar += alocar_indices(lin, col -1, cont,l,c,matriz); if (verificar == 4){ // Ponto de Para para a mimha funcao de recursividade return 1; } } return 1; } //************************************************************* //* Funcao aloca_matriz: Cria a Matriz //* l = linha //* c = coluna //************************************************************* int **aloca_matriz (int l, int c){ int **tab; // Ponteiro p/ ponto que contem a matriz int i; if (l < 1) { printf ("** ERRO: INAVLIDO PARAMETRO **\n"); return (NULL); } tab = (int **) calloc (l, sizeof(int *)); // Linhas da Matriz if (tab == NULL) { printf ("** ERRO MEMORIA INSUFICIENTE **"); return (NULL); } for ( i = 0; i < c; i++ ) { tab[i] = (int*) calloc (c, sizeof(int)); // Colunas da Matriz if (tab[i] == NULL) { printf ("** ERRO MEMORIA INSUFICIENTE **"); return (NULL);
} } return (tab); } //************************************************************* //* Funcao imprime_matriz: Realiza a impressao na tela das //* matrizes com as informacoes de parede, queijo , ... //* l = linha //* c = coluna //* **matriz = matriz //************************************************************* void imprime_matriz(int l, int c, int **matriz){ int i; int j; int k; for(i = 0 ; i < l ; i++){ for(k = 0 ; k < c ; k++){ if(matriz[i][k] == -4){ if(i == 0){ printf("+ "); }else{ printf("+-"); } } else{ printf("+-"); } } printf("+\n"); for(j = 0 ; j < c ; j++){ switch (matriz[i][j]){ case -1: printf("|R"); break; case -2: printf("|Q"); break; case -3: printf("|#"); break; case -4: if(c==0) printf(" "); else printf("| ");
break; case -9: printf("|."); break; default: printf("| "); break; } } if(matriz[i][k-1] == -4){ printf("\n"); }else{ printf("|\n"); } } for(k = 0 ; k < c ; k++){ if(matriz[i-1][k] == -4){ printf("+ "); } else{ printf("+-"); } } printf("+"); } //************************************************************* //* Funcao limpa_matriz: Limpa a Matriz //* l = linha //* c = coluna //* **matriz = Matriz que ser limpa //************************************************************* void limpa_matriz (int l,int c, int **matriz){ int i; int j; for(i = 0 ; i < l ; i++){ for(j = 0 ; j < c ; j++){ matriz[i][j] = 0; } } } //************************************************************* //* Funcao encontra_caminho: realiza a leitura dos campos aps //* aps a colocacao dos indices, e marca o caminho do Rato //* para o queijo //* lin = linha
//* col = coluna //* num = variavel para informar o valor do caminho e permitir // a dua subtracao para determinacao do caminho //* **matriz = Matriz principal com os indices colocados //* **matriz_rato_queijo = Matriz que ter somente o melhor //* caminho registrado //************************************************************* int encontra_caminho(int lin,int col, int num, int **matriz, int **matriz_rato_queijo){ int retorno = 0; matriz_rato_queijo[lin][col]=-9; num --; if(lin+1>=0){ if(matriz[lin+1][col] == num){ col = col; lin = lin + 1; } } if(col+1>=0){ if(matriz[lin][col+1] == num){ col = col + 1; lin = lin; } } if(lin-1>=0){ if(matriz[lin-1][col] == num){ col = col; lin = lin - 1; } } if(col-1>=0){ if(matriz[lin][col-1] == num){ col = col - 1; lin = lin; } } if(num < 2||retorno == 1){ return 1; } retorno = encontra_caminho(lin,col,num,matriz,matriz_rato_queijo); } //************************************************************* //* Funcao encontra_caminho_saidas: realiza a leitura dos campos aps //* aps a colocacao dos indices, e marca o caminho do Queijo
//* para a Melhor Saida //* lin = linha //* col = coluna //* num = variavel para informar o valor do caminho e permitir // a dua subtracao para determinacao do caminho //* **matriz = Matriz principal com os indices colocados //* **matriz_queijo_saida = Matriz que ter somente o melhor //* caminho registrado para a saida //************************************************************* int encontra_caminho_saidas(int lin, int col, int **matriz, int **matriz_queijo_saida){ int num = 0; int l_m = 0; int c_m = 0; int l = 0; int c = 0; int retorno = 0; for(l=0; l<lin ; l++){ for(c=0 ; c < col ; c++){ if(matriz[l][c] == -4){ // Verifico se a casa tem saida // Qual o menor caminho pelos numero ao lado da celula if(l+1>=0 && l+1<lin){ if(matriz[l+1][c] > 0){ if(num>0){ if(num > matriz[l+1][c]){ c_m = c; l_m = l + 1; num = matriz[l+1][c]; } } else{ num = matriz[l+1][c]; c_m = c; l_m = l + 1; } } } if(c+1>=0 && c+1 < col ){ if(matriz[l][c+1] > 0){ if(num>0){ if(num > matriz[l][c+1]){ c_m = c + 1; l_m = l; num = matriz[l][c+1]; } }
else{ c_m = c + 1; l_m = l; num = matriz[l][c+1]; } } } if(l-1>=0){ if(matriz[l-1][c] > 0){ if(num>0){ if(num > matriz[l-1][c]){ c_m = c; l_m = l - 1; num = matriz[l-1][c]; } } else{ c_m = c; l_m = l - 1; num = matriz[l-1][c]; } } } if(c-1>=0){ if(matriz[l][c-1] > 0){ if(num>0){ if(num > matriz[l][c-1]){ c_m = c - 1; l_m = l; num = matriz[l][c-1]; } } else{ c_m = c - 1; l_m = l; num = matriz[l][c-1]; } } } } } } if ( num == 0 ) return 0;