UVA133救济金发放
题目
n(n<20)个人站成一圈,逆时针编号为1~n。有两个官员,A从1开始逆时针数,B从n开始顺时针数。在每一轮中,官员A数k个就停下来,官员B数m个就停下来(注意有可能两个官员停在同一个人上)。接下来被官员选中的人(1个或者2个)离开队伍。
输入n,k,m输出每轮里被选中的人的编号(如果有两个人,先输出被A选中的)。例如,n=10,k=4,m=3,输出为4 8, 9 5, 3 1, 2 6, 10, 7。注意:输出的每个数应当恰好占3列。
输入:
10 4 3
输出:
_ _ 4_ _ 8,_ _ 9_ _ 5,_ _ 3_ _ 1,_ _ 2_ _ 6,_ 10,_ _ 7
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int MAX=25; int a[MAX],n,k,m; int go(int p,int d, int t) { //p position d 1/-1 t 步长 while(t--) { do { p=(p+d+n-1)%n+1; }while(a[p]==0);//寻找下一个不为0的数字, } return p; } int main() { while(scanf("%d%d%d",&n,&k,&m)==3&&n) { for(int i=1;i<=n;i++) a[i]=i; int left=n;//剩余人数 int pa=n,pb=1;//确定两个官员数时的初始位置 while(left) { pa=go(pa,1,k); pb=go(pb,-1,m); printf("%3d",pa);left--; if(pb!=pa) { printf("%3d",pb);left--; } //将 pa pb所在位置置为0,表示领完救济金离开 a[pa]=0;a[pb]=0; if(left) printf(","); } printf("\n"); } return 0; }