您的位置:首页 > 其它

poj 1012 Joseph

2013-08-15 20:54 363 查看
Joseph

Time Limit: 1000MSMemory Limit: 10000K
Total Submissions: 44668Accepted: 16847
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
3
4
0

Sample Output
5
30

Source

Central Europe 1995

Joseph

Time Limit: 1000MS
Memory Limit: 10000K
Total Submissions: 44668
Accepted: 16847
Description
约瑟夫问题是众所周知的。对于那些并不熟悉原来问题的人,在这里重述一下问题:对于一共n个人,编号1,2,…,n,站成一圈,每第m个人离开,然后剩下的最后一个人将幸存。约瑟夫比较聪明,知道哪个位子不用死,因而能够活下来把事件的讯息传达给我们。比如当n=6时m=5人将按照5,4,6,2,3一次离开,然后1将存活
假设那里有k个好人和k个坏人。在一圈中,前k个是好人后k个是坏人。你必须设计一个最小的m可以让坏人先于好人离开。
Input
输入包括分开的几行数据,每行数据就是一个k值。输入的最后一行是一个0。你可以认为0<k<14
Output
输出文件将包括几行分开的数据,每行输出一个m,对应于输入的k值
Sample Input
3 4 0Sample Output
5 30Source
Central Europe 1995

这道题用约瑟夫最原始的方法递推貌似都可以过,这里用的方法是以前在哪个帖子里看到的(自己是没脑子想了.....),只考虑倒数第二个死的坏人,则最后一个死的坏人一定是在m位k+1的整数倍,或者k+1的整数倍+1,因为就剩下两个坏人了,前一个死得数k+1的整数倍+1,后一个死得数k+1的整数倍,之所以不是k+2是因为一共就k+1个人了......效率不算太高,不打表的话就会t,看来测试数据里面有不少重复数据....挺坑的。

#include<iostream>
#include<cmath>
#include<algorithm>
#include <stdio.h>
#include <string.h>

int ifright(int m);
int k;
int main(void)
{
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
int Joseph[14] = {0};
while(scanf("%d", &k) && k)
{
if (Joseph[k]){
printf("%d\n", Joseph[k]);
continue;
}

int i = 0;
int m = 0;
while(++i){
if (ifright(m = i * (k + 1)))
{
Joseph[k] = m;
printf("%d\n", m);
break;
}
if (ifright(m + 1))
{
Joseph[k] = m + 1;
printf("%d\n", m + 1);
break;
}
}
}
}

int ifright(int m)
{
int alive = 2*k;
int start = 0, now;
for (int i = 0;i < k;i ++)
{
now = (start + m - 1 ) % alive;
//		printf("now = %d\n", now);
if (now < k)
return 0;
alive--;
start = now;
if (now == alive)
start = 0;
}
return 1;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: