约瑟夫环问题:一圈共有N个人,开始报数,报到M的人自杀,然后重新开始报数,问最后自杀的人是谁?
HDU 2.2.2
#include<iostream>
using namespace std;
int joseph[10001];
int ans[10001];
int main()
{
int k;
while(cin>>k&&k)
{
if(joseph[k]!=0)
{
cout<<joseph[k]<<endl;
continue;
}
int m=1;
int n=2*k;
int i;
for(i=1;i<=k;i++)
{
ans[i]=(ans[i-1]+m-1)%(n-i+1);
}
if(ans[i]<k)
{
i=0;
m++;
}
joseph[k]=m;
cout<<m<<endl;
}
return 0;
}
*/
#include <iostream>
using namespace std;
int ans[21];
int joseph[21];
int main()
{
int k;
while(cin>>k&&k){
if(joseph[k] != 0){//如果之前已经遇到过相同的k值
cout<<joseph[k]<<endl;//则直接输出。
continue;
}
int m = 1;//最小间隔是1
int n = 2*k;//计算总人数
int i;
for(i = 1 ; i <= k ; ++i)
{//判断一个m值在k轮里面是否会杀掉好人
ans[i] = (ans[i-1]+m-1)%(n-i+1);//计算下一个要杀掉的位置.(ans[i-1]+m-1)是下一个要杀掉的索引.(n-i+1):当前剩余人数
if(ans[i] < k)
{//如果杀掉了好人
i=0;//说明当前m值不合适,从心开始试验
m++;//去下一个m值
}
}
joseph[k] = m;//额k如果已经求出m值了就记录下来。下一次如果是相同的k就不需要再次计算了
cout<<m<<endl;
}
return 0;
}