Sei sulla pagina 1di 16

FUNDAO DE ESTUDOS SOCIAIS DO PARAN COORDENAO DE BACHARELADO EM SISTEMAS DE INFORMAO CURSO DE BACHARELADO EM SISTEMA DE INFORMAO

TRABALHO: RATINHO ESFOMEADO

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

TEMA: O RATINHO ESFOMEADO

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;

retorno = encontra_caminho(l_m,c_m,num,matriz,matriz_queijo_saida); return 1; }

Potrebbero piacerti anche