约瑟夫环问题的演变。
题意:k个好人站前面,k个坏人站后面,排成2k的一列,报数每到m杀掉一个,最后要求剩下k个好人,问最小的m是多少。
思路:因为k很小,但是查询次数多,所以打表,记录每个k的结果,每次杀掉一个人后,以下一个人为新的队列下标0,计算出来好人的开始和结束下标,以判断下次是否会杀到好人。
#include<iostream>
using namespace std;
int ans[15];
int main()
{
int k;
for(k=1;k<14;k++)
{
if(!k) break;
int t=k+1;
while(1)
{
int n=2*k;
int gs=0,ge=k-1;
while(n>k)
{
int kill=(t-1)%n;
if(kill>=gs&&kill<=ge) break;
if(gs>kill)
{
gs=gs-kill-1;
ge=ge-kill-1;
}
else
{
gs=gs+n-kill-1;
ge=ge+n-kill-1;
}
n--;
}
if(n==k)
{
ans[k]=t;
break;
}
t++;
}
}
while(cin>>k)
{
if(!k) break;
cout<<ans[k]<<endl;
}
}