参考:http://blog.csdn.net/wuzhekai1985/article/details/6628491和http://www.2cto.com/kf/201307/227327.html
约瑟夫环问题:从第一个人开始数数,相隔m的出列如m=5 那么出列的为 1 ,6,11,。。。。。求解使得第二个人最后出列时m的值
模拟的写法
#include <stdio.h>
#include <string.h>
int next[152],vis[152];
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n)
{
int m=1;
int find=0;
memset(next,0,sizeof(next));
for(int i=1;i<n;i++)
next[i]=i+1;
next[n]=1;
while(!find)
{
m++;
memset(vis,0,sizeof(vis));
int cutnum=n;
vis[1]=1;
cutnum--;
int from=1;
while(cutnum>1)
{
int num=0;//统计相隔的数目
int nextcut=from;//从from开始查数
while(num<m)
{
nextcut=next[nextcut];
if(vis[nextcut]==0)
num++;
}
vis[nextcut]=1;
from=nextcut;
cutnum--;
if(from==2&&cutnum!=1)
break;
}
if(cutnum==1&&vis[2]==0)
{
find=1;
}
}
printf("%d\n",m);
}
return 0;
}
约瑟夫环通用公式的写法
约瑟夫环的通用公式为:
f[i]=(f[i-1]+m)%i;(编号从0开始)
m为相隔的数,i从2到n。在这道题中,将人的个数从0开始编号,而不是像题目中给出的从1开始编号。
#include <stdio.h>
#include <string.h>
int m,n;
int judge()
{
int from=0;
for(int i=2;i<n;i++)
from=(from+m)%i;
if(from+1==1) return 1;//最后的那栋楼刚开始编号为1.即第二栋楼。
else
return 0;
}
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
m=1;
while(!judge())
m++;
printf("%d\n",m);
}
return 0;
}