约瑟夫环:只去掉所有坏人的问题。
有n个人围坐在一个圆桌周围,把这n个人依次编号为1,…,n。从编号是1的人开始报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m个人又出列,…,如此反复直到所有的人全部出列为止。比如当n=6,m=5的时候,出列的顺序依次是5,4,6,2,3,1。现在的问题是:假设有k个好人和k个坏人。好人的编号的1到k,坏人的编号是k+1到2k。我们希望求出m的最小值,使得最先出列的k个人都是坏人#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
int k,m;
int first,flag;
int check(int mm)
{
int ans=(first+m-1)%mm; //杀死的人 去摸防止溢出
if(ans>=k) //大于k说明坏人被杀死了满足答案
{
first=ans;
return 1;
}
return 0; //好人被杀,不行,不是我们的答案
}
int main()
{
cin>>k;
m=k;
while(flag==0)
{
flag=1,first=0; //找到答案的标记
for(int i=0;i<k;i++) //枚举
{
if(check(2*k-i)==0)
{
flag=0;
break;
}
}
m++;//答案会多算
}
cout<<m-1<<endl;
return 0;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
int ans=(first+m-1)%mm; 这里为什么要first+m-1?
if(ans>=k) 这里不能只>k吗??