poj1012

来源:互联网 发布:mac mysql phpmyadmin 编辑:程序博客网 时间:2024/05/20 00:17

题意:
有k个坏人k个好人坐成一圈,前k个为好人(编号1~k),
后k个为坏人(编号k+1~2k).现在有一个报数m,从编号为1的人开始报数,
报到m的人就要自动死去。问当m为什么值时,
可以使得在出现好人死亡之前,k个坏人先全部死掉?
算法:模拟,从k+1枚举。
ps:约瑟夫问题公式
(1)令f[i]表示i(0~i-1)个人,报m,最后胜利者的编号,
递推公式  f[1]=0;  f[i]=(f[i-1]+m)%i; (i>1)
(2)有n个人(0,...,n-1),数m,
   则第i轮出局的人为f(i)=(f(i-1)+m-1)%(n-i+1),f(0)=0;

#include <iostream>

#include <cstdio>
#include <cstring>


using namespace std;


int man[40],j[20];//j记录算出的值,防止重复计算超时


int kill(int n,int start,int num)
{
     int i=start-1,sum=0;
     if (i==0) i=n; //环链注意首尾相连
     while (sum!=num)
     {
          i++;
          if (i==n+1) i=1;
          if (man[i]==1) sum++;


     }
     return i;
}


int main()
{
    int k,n,m,flag,i;
    freopen("in.txt","r",stdin);
   while (cin>>k)
   {
    if (k==0) break;
    n=2*k;
    flag=0;
    m=k;
    while (!flag&&j[k]==0)
    {
         int start=1,alive=n,dead;
         for (i=1;i<=n;i++) man[i]=1;
         m++;
         flag=1;
         for (i=1;i<=k&&flag==1;i++)
         {
              int num;
              if (m%alive>0) num=m%alive;else num=alive;//m%alive==0 时的处理
              dead=kill(n,start,num);
              if (dead<=k&&dead>0) flag=0;
              else
              {
                   man[dead]=0;
                   alive--;
                   start=dead+1;
                   if (start==n+1) start=1;
              }
         }
    }
    if (j[k]==0) j[k]=m;
    cout<<j[k]<<endl;
   }
    return 0;
}

0 0
原创粉丝点击