[Prévia] [Próxima] [Prévia por assunto] [Próxima por assunto]
[Índice cronológico]
[Índice de assunto]
Josephus
Olá,
Encontrei uma solução para o Problema de Josephus... Ela não entra para
o concurso dos Toblerones, pois é dependente de m, mas estou colocando aqui,
pois é a que menos gasta memória das que eu consegui descobrir...
A idéia por trás da solução é que os mortos iniciais são os múltiplos de
m, mas quando i.m > n, deve-se subtrair n e somar o número de mortos entre a
primeira pessoa e a pessoa (i.m - n). O valor dessa quantidade a ser somada
pode ser retirada do fato que (supondo ainda que i.m < 2n) deve-se somar uma
pessoa quando existir um múltiplo de m que existir neste intervalo e mais 1
a cada intervalo de m vivos (retirando os múltiplos de m), pois esses já
devem ter sido retirados.
Esta "transformação" é conseguida aplicando a fórmula (retirada fazendo
alguns cálculos e através de algumas observações empíricas):
x = floor(m(x-n)/(m-1) - 1/(m-1))
onde x inicialmente é iniciado como x = i.m e é o número da pessoa a ser
morta.
Até agora, aparentemente, esta observação só serviria para i.m < 2n,
mas, fazendo um pouco mais de cálculo, é possivel observar que, se após a
primeira aplicação da equação x > n, pode-se aplicar novamente ela até que o
valor caia no intervalo desejado. Sem números, este resultado se deve ao
fato de, quando é subtraído pela primeira vez n, é somada a "correção". Se
este valor não estiver no intervalo de pessoas possivelmente vivas, ao
aplicar a correção novamente, essas correções se somam caindo no intervalo
desejado (soma 1 a cada múltiplo de m, mais 1 a cada múltiplo de m nos que
restaram, e assim por diante).
Bom, qualquer pergunta ou sugestão sobre o algoritmo (por exemplo, como
gerar a próxima pessoa a partir da anterior sem ter uma expressão de tamanho
crescente e, portanto, de tempo de processamento também crescente) é só
fazer!
Aí vai o programa (que repito, não atende as especificações do concurso
valendo os Toblerones):
#include <stdio.h>
main()
{
int n,x,i,m;
printf("\n\n SOLUCAO DO PROBLEMA DE JOSEPHUS \n\n");
printf("Entre com o numero de pessoas (n): ");
scanf("%d",&n);
printf("Entre com o valor do \"passo\" (m): ");
scanf("%d",&m);
printf("\n A sequencia de pessoas a serem mortas é:\n");
for (i=1;i<=n;i++)
{
x=m*i; // se n fosse infinito seria a i-esima pessoa a ser morta
while (x>n) // ajusta x enquanto x > n
x=(m*(x-n)-1)/(m-1); // arredonda para baixo!
printf("%d, ",x);
}
printf("\b\b.\n\n");
return(0);
}
É isso aí!
[]'s
Michel Leonard Goldstein