约瑟夫问题
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 253 测试通过 : 37
总提交 : 253 测试通过 : 37
比赛描述
17世纪的法国数学家加斯帕在《数目的游戏问题》中讲的一个故事:15个教徒和15 个非教徒在深海上遇险,必须将一半的人投入海中,其余的人才能幸免于难,于是想了一个办法:30个人围成一圆圈,从第一个人开始依次报数,每数到第九个人就将他扔入大海,如此循环进行直到仅余15个人为止。问怎样排法,才能使每次投入大海的都是非教徒。这个故事的问题是经典的约瑟夫问题。
现在我们知道有n个教徒和非教徒,其中非教徒数为m,将他(她)们按从1到n的次序放置到圆圈中,报数为k,要将所有非教徒投入大海,请按递增次序给出非教徒在圆圈中的次序。
输入
每行是用空格分开的三个整数,第一个是 n, 第二个是 m,第三个是k ( 0 <= m<n <=100,0 <k <=100)。最后一行是:
0 0 0
输出
对于每个测试用例,输出一行,依次包含:
l “Case #:”,#表示用例序号。
l m个非教徒在圆圈中的次序,以空格分隔;如没有非教徒,则无需输出。
样例输入
6 2 9
12 4 8
8 3 2
0 0 0
样例输出
Case 1: 1 3
Case 2: 1 4 8 11
Case 3: 2 4 6
提示
题目来源
NUPT
/* Wrong Answer at Test 2
#include<iostream>
int main(){
bool drop[101];
int n,m,k,i,j,cas=0;
while(scanf("%d%d%d",&n,&m,&k)==3 && n){
cas++;
printf("Case %d:",cas);
if(!m){
printf("\n");
continue;
}
memset(drop,0,sizeof(drop));
i = 0;
while(m--){
j = k;
while(j){
i = (i+1)%n;
if(!drop[i]){
j--;
}
}
drop[i] = 1;
}
for(i=0;i<n;i++){
if(drop[i]){
printf(" %d",i);
}
}
printf("\n");
}
}
*/
#include<iostream>
int main(){
bool drop[101];
int n,m,k,i,j,cas=0;
while(scanf("%d%d%d",&n,&m,&k)==3 && n){
cas++;
printf("Case %d:",cas);
if(!m){
printf("\n");
continue;
}
memset(drop,0,sizeof(drop));
i = -1; //WA2
while(m--){
j = k;
while(j){
i = (i+1)%n;
if(!drop[i]){
j--;
}
}
drop[i] = 1;
}
for(i=0;i<n;i++){
if(drop[i]){
printf(" %d",i+1);
}
}
printf("\n");
}
}