約瑟夫環問題的演變。
題意: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;
}
}