题目大意:存在一个约瑟夫环,给出一个k,表示编号是1到k是好人,k+1到2*k是坏人,要求一个最小的m,使得所有的坏人都在好人之前出圈。

解题方法:约瑟夫问题是一个很经典的问题,有下面两个特点:
              1)s[i]表示第i个出圈的人是谁,则有s[i]=(s[i]+m-1)%n (这里的n指得是剩下的人数)
              2)w[i]表示i个人完报到m则出圈游戏的最后获胜者是谁,则有f[i]=(f[i-1]+m)%i

              这题,只要用第一个性质进行模拟就可以了,枚举m的大小,进行验证即可。
 1#include <iostream>
 2#include <cstdio>
 3
 4using namespace std;
 5
 6int a[14];
 7bool f(int n,int m)
 8{
 9  int i,s=1,num=1,k=n;
10  n=n*2;
11  for(i=1;i<=k;i++)
12  {
13     s=(s+m-1)%n;
14   // cout << s << " ";
15   if(s==0)s=n;
16   n--;
17   if(s<=k)return false;
18  }
 return true;
19}

20int main()
21{
22 int n,i,j,len;
23 for(i=1;i<14;i++)
24    {
25     for(j=i+1;;j++)
26     {
27      if(f(i,j))
28      {a[i]=j; break;}
29  }

30 }

31 while(scanf("%d",&n),n)
32 {printf("%d\n",a[n]);}
33 return 0;
34}

35