Joseph
Time Limit: 1000MS Memory Limit: 10000K
Total Submissions: 55080 Accepted: 21055
DescriptionThe 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
3
4
0
Sample Output
5
30
学习到的知识:
1.服务器打表处理
//最后就是由于本题k值有限,只有13个值,
//那么POJ的数据测试就极有可能重复测试每个k值的结果,
//为了节省总体时间
//我们的程序只在第一次得到k值的时候计算m值,
//然后保存下来,
//当k值再次出现时,
//就直接把保存的结果输出,
//不再计算m。
2.约瑟夫环的公式:
从编号0—n-1个人:
arr[i]=(arr[i-1]+m)%n;//从0开始报数
arr[i]=(arr[i-1]+m)%(n-1);//从1开始报数
附上代码:
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int k;
int arr[50],joe[50];
memset(joe,0,sizeof(joe));
while(~scanf("%d",&k)&&k)
{
int m=1;
memset(arr,0,sizeof(arr));
if(joe[k])
{
printf("%d\n",joe[k]);//这是在服务器打表的处理,没有则TLE。
continue;
}
arr[0]=0;
for(int i=1;i<=k;i++)
{
arr[i]=(arr[i-1]+m)%(2*k-i);
if(arr[i]<k)
{
i=0;
m++;
}
}
joe[k]=m;
printf("%d\n",m);
}
return 0;
}
知识来源:
1.CNDS博客名为:小優YoU
2.度娘