题目翻译:
为了努力缩小(减少)救济队伍,新国家的绿色劳动犀牛党已决定采取以下策略。每天所有的领救济金人将被放置在一个大圆圈中,面向内部 。有人被任意选为1号,其余的被逆时针编号到N(将站在1的左侧) 从1开始并逆时针移动,一名劳工计算k个申请人;另一名官员从N开始并顺时针移动,并计算m个申请人。然后将被选中去接受再培训。如果两个官员选择的是同一个人,她(他)将被指派成为一个政治家。然后每个官员开始对下一个可用的人进行计数并且过程持续进行直到无人离开为止。请注意,两名受害者(对不起,受训人员)同时离开该圆圈,所以一名官员可能选择被另一名官员选择的人。
输入
编写一个程序,将连续读入(按这种顺序)三个数字(N,k和m;k, k,m> 0,
0 <N <20)并确定申请人被送往再训练的顺序,每三个数字将在一个单独的行上,并且数据的结尾通过三个零(0 0 0)发出信号。
输出
对于每个三元组,输出一行数字指定人员被选择的顺序,每个数字应该在三个字符的字段中,对于数字对逆时针选择的官员优先,由逗号分开连续对(尾无逗号).
注意:下面的Sample Output中的符号 ⊔代表一个空格。
解题思路:虽然是模拟,这个题的输出wa了三次,当然如果输出可以了,那就简单了,注意取模。
解题代码:
#include<cstdio>
#include<cstring>
#include<cstdio>
#include<iostream>
#include<iomanip>
using namespace std;
const int N=26;
int a[N];
int n,k,m;
int goto(int p,int d,int t){
while(t--){
do{
p=(p+d+n-1)%n+1;
}while(a[p]==0);
}
return p;
}
int main(){
while((cin>>n>>k>>m)&&(n||k||m)){
for(int i=1;i<=n;i++) a[i]=i;
int left=n;
int p1=n,p2=1;
while(left){
p1=goto(p1,1,k);
p2=goto(p2,-1,m);
cout<<setw(3)<<p1;
left--;
if(p1!=p2) {
cout<<setw(3)<<p2;
left--;
}
a[p1]=a[p2]=0;
if(left) cout<<",";
}
cout<<endl;
}
return 0;
}