Joseph

来源:互联网 发布:我为什么离开华为 知乎 编辑:程序博客网 时间:2024/05/17 22:31

Joseph

Description

The Joseph's problem is notoriously known. For those  who are not familiar with the original problem: from among n people, numbered 1,  2, . . ., n, standing in circle every mth is going to be executed and only the  life of the last remaining person will be saved. Joseph was smart enough to  choose the position of the last remaining person, thus saving his life to give  us the message about the incident. For example when n = 6 and m = 5 then the  people will be executed in the order 5, 4, 6, 2, 3 and 1 will be saved.

Suppose that there are k good guys and k bad guys. In the circle the  first k are good guys and the last k bad guys. You have to determine such  minimal m that all the bad guys will be executed before the first good guy.

Input

The input file consists of separate lines containing  k. The last line in the input file contains 0. You can suppose that 0 < k < 14.

Output

The output file will consist of separate lines  containing m corresponding to k in the input file.

Sample Input

340

Sample Output

530
http://poj.org/problem?id=1012
解题思路:
把k个好人和k个坏人按0,1,2,...,K-1的方式编码,因为只需把k个坏人在好人出列前全部出列即可,所以不需要知道具体的出列顺序,只需保证每次出列的人的序号>=K即可,在这里我采用了每次有人出列之后就重新从0递增1排列序号的方法,通过模拟和数学推导得到每次出列的序号的递推公式为:j[i+1]=(m+j[i]-1)%(n-i),m为所求值,i+1为出列的序号,j[0]=0。
因为当全列只剩下一个坏人的时候,最后第二个坏人可能在最后一个坏人的前面也可能在它的后面。如果是在它的后面,数数的起点即为第一个好人,刚好到它,即为整除,即m=t(k+1),如果是在它的前面,数数的起点即为它本身,到它,即余1,即m=t(k+1)+1。t>=1,利用这个条件进行筛选。
本来我就是利用第二个推理来筛选数据和第一个公式来测试数据,代码提交之后,显示时间超出,后来参考网上的方法,采用预先打表的方式,把13组数据全部算出来并存入数组中,就通过了。
 
#include <iostream>using namespace std;int main(){int k,n,m,i,j,t,T[14];memset(T,0,sizeof(T));for (k=1;k<14;k++){n=2*k;t=1;while (t>=1){j=0;m=t*(k+1);for (i=0;i<k;++i){j=(m+j-1)%(n-i);if (j<k)break;}if (i==k&&j==k)break;else{j=0;++m;for (i=0;i<k;++i){j=(m+j-1)%(n-i);if (j<k)break;}}if (i==k&&j==k)break;++t;}T[k]=m;}while (cin>>k&&k!=0)cout<<T[k]<<endl;return 0;}

原创粉丝点击