|
Although many good programmers have been saved since Joseph spread out this information, Joseph's cousin introduced a new variant of the malignant game. This insane character is known for its barbarian ideas and wishes to clean up the world from silly programmers. We had to infiltrate some the agents of the ACM in order to know the process in this new mortal game.
In order to save yourself from this evil practice, you must develop a tool capable of predicting which person will be saved.
The Destructive Process
The persons are eliminated in a very peculiar order; m is a dynamical variable, which each time takes a different value corresponding to the prime numbers' succession (2,3,5,7...). So in order to kill the ith person, Joseph's cousin counts up to the ith prime.
InputIt consists of separate lines containing n [1..3501], and finishes with a 0.
OutputThe output will consist in separate lines containing the position of the person which life will be saved.
Sample Input6Sample Output
4
举个例子,6个人分别编号1 2 3 4 5 6,2号出队,剩下1 3 4 5 6,然后从3号开始循环往后数3下,5号出队,剩下1 3 4 6,然后从6号循环往后数5下,6号出队,剩下1 3 4,然后从1号开始循环往后数7下,1号出队,剩下3 4,然后从3号开始循环往后数11下,3号出队,最后剩下4.
我们可以模仿上面程序,只是m在动态变化,我们先用数组存储连续的素数。然后在循环中不断更换m值。代码如下:
#include <iostream>
#include <cmath>
using namespace std;
bool is_prime(int x)
{
int i;
int y=sqrt(x);
for(i=2;i<=y;i++)
{
if(x%i==0)
{
return false;
}
}
return true;
}
int main()
{
int i=3,j=2,n,prime[3501];
prime[1]=2;
for(i=3;j<3501;i+=2)
{
if(is_prime(i))
{
prime[j++]=i;
}
}
while((cin>>n)&&n)
{
int s=0;
j=n-1;
for(i=2;i<=n;i++)
{
s=(s+prime[j--])%i;
}
cout<<s+1<<endl;
}
return 0;
}
2.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.
InputThe input file consists of separate lines containing k. The last line in the input file contains 0. You can suppose that 0 < k < 14.
OutputThe output file will consist of separate lines containing m corresponding to k in the input file.
Sample Input3 4 0
Sample Output5 30
执行k次后,还剩下k人,这k个人编号分别为0,1,2...k-1,将他们转化到2k个人中的编号,编号必须在1到k之间。我们可以遍历m,找到一个符合要求的m值,其中m%2k>k或者m%2k==0.代码如下:
#include <iostream> using namespace std; int main() { int k; int a[15]; a[11]=459901; a[12]=1358657; a[13]=2504881; a[14]=13482720; while(cin>>k&&k) { if(k>=11) { cout<<a[k]<<endl; continue; } int s,i,m,node,flag; for(m=k+1;;m++) { flag=1; if((m%(2*k)>k)||(m%(2*k)==0)) { for(node=0;node<k;node++) { s=node; for(i=k+1;i<=2*k;i++) { s=(s+m)%i; } if((s+1)>k) { flag=0; break; } } } else { m+=k-1; continue; } if(flag) { cout<<m<<endl; break; } } } return 0; }
由于当k大于等于11时该程序会超时,所以只能先算出k=11,12,13,14时的m值...