quinta-feira, 3 de dezembro de 2009

APLICAÇÃO - LISTA CIRCULAR ENCADEADA


Problema de Josephus: Este problema postula um grupo de soldados circundados por uma força inimiga esmagadora. Não há esperanças na vitória sem a chegada de reforços, mas existe somente um cavalo disponível para escapar. Os soldados entram em um acordo para determinar qual deles deverá escapar e trazer ajuda. Eles formam um círculo e um número n é sorteado num chapéu. Um de seus nomes é sorteado também. Começando pelo soldado cujo nome foi sorteado, eles começam a contar ao longo do círculo em sentido horário. Quando a contagem alcança n, esse soldado é retirado do círculo, e a contagem reinicia com o soldado seguinte. O processo continua de maneira que, toda vez que n é alcançado, outro soldado sai do círculo. Todo soldado retirado do círculo não entra mais na contagem. O último soldado que restar deverá montar no cavalo e escapar. Considerando um número n, a ordenação dos soldados no círculo e o soldado a partir da qual começa a contagem, o problema é determinar a seqüência na qual os soldados são eliminados do círculo e o soldado que escapará. A entrada para o programa é o número n, a lista de nomes (devem ser armazenados em uma lista circular encadeada) que será o seqüenciamento do círculo no sentido horário e o nome do soldado onde deve iniciar a contagem. Para indicar o final da entrada de nomes o usuário deve digitar dois pontos (:). O programa deve imprimir os nomes na seqüência em que são eliminados e o nome do soldado que escapará. OBS: Você pode utilizar como nomes para os soldados as letras do alfabeto: soldado A, B, C,  D, etc.


Eu fiz assim:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct circulo
{
  char nome[50];
  struct circulo *prox;
}nodo;
nodo *lista;
void cria_nodo(nodo **aux)
  {
  *aux=(nodo*) malloc(sizeof(nodo));
  }
void insere(nodo **l,char n[50])
{
  nodo *aux,*aux2;
  cria_nodo(&aux);
  strcpy(aux->nome,n);
  aux->prox=NULL;
  if(*l==NULL)
  {
     *l=aux;
  }
  else
  {
     aux2=*l;
     while(aux2->prox!=NULL)
     {
        aux2=aux2->prox;
     }
     aux2->prox=aux;
  }
}
void fim(nodo **l)
{
  nodo *aux;
  aux=*l;
  while(aux->prox!=NULL)
  {
     aux=aux->prox;
  }
  aux->prox=*l;
}

void le()
{
  char nome[50]={"\0"};
  while(nome[0]!=':')
  {
     printf("Digite o nome do soldado: \n");
     gets(nome);
     if(nome[0]!=':')
     {
        insere(&lista,nome);
        nome[0]='\0';
     }
     else
     {
        fim(&lista);
        printf("FIM DA LINHA!\n");
     }
  } 
}
void mata_soldado(nodo **l,int num)
{
  int i;
  nodo *aux,*aux2,*fre;
  aux2=*l;
  aux=aux2->prox;
  while(aux!=aux->prox)
  {
     for(i=1;i<=num;i++)
     {
        if(i==num)
        {
           printf("morreu:");
           puts(aux->nome);
           printf("\n");
           fre=aux;
           aux2->prox=aux->prox;
           aux2=aux2->prox;
           aux=aux->prox;
           aux=aux->prox;
           free(fre);
        }
        else
        {
           aux2=aux;
           aux=aux->prox;
        }
     }
  }
  printf("O soldado sortudo que se salvou foi o %s \n",aux->nome);
  free(aux);
}
int main(int argc, char *argv[])
{
  int n;
  le();
  printf("Digite o número sorteado \n");
  scanf("%d",&n);
  mata_soldado(&lista,n);
  system("PAUSE");   
  return 0;
}




2 comentários:

  1. Valeu mesmo ajudou muito como exmplo

    ResponderExcluir
  2. como eu faria para fazer esse mesma implementaçao so que usando lista duplamente encadeada?

    ResponderExcluir