救济金发放(模拟题打卡)
一、题目
n(n < 20)个人站成一圈,逆时针编号为1~n。有两个官员,A从1开始逆时针数,B从n开始顺时针数。在每轮中,官员A数k个停下,官员B数就停下来(注意有可能停在同一个人上)。接下来被选中的一个(或两个人离开)。输出输入格式参见UVa233。
二、解题思路
这是一道简单题,但处理不好很可能写复杂。我们用数组存储一圈,将离开的人标记。每次数到被标记的,跳过就可以了。
三、代码
1 #include<stdio.h> 2 #include<iostream> 3 #include<string.h> 4 using namespace std; 5 6 const int maxn = 20 + 10; 7 int status[maxn]; 8 int seq[maxn]; 9 10 int go(int pos, int k, int t,int n) 11 { 12 while (t--) 13 { 14 do 15 { 16 pos = (pos + k + n - 1) % n + 1; //由于编号是1~n,不是从0开始,所以先加1后减1 17 } while (status[pos]); //走到下一个未被选中过的位置 18 } 19 return pos; 20 } 21 int main() 22 { 23 int n, k, m; 24 while (scanf("%d%d%d",&n,&k,&m) == 3 && n) 25 { 26 memset(status, 0, sizeof(status)); 27 int left = n; 28 int p1 = n, p2 = 1; //由于刚开始出发时,包括本身,所以A从n算起,B从1算起 29 while (left) 30 { 31 p1 = go(p1, 1, k, n); 32 p2 = go(p2, -1, m, n); 33 printf("%3d", p1); 34 left--; 35 if (p2 != p1) 36 { 37 printf("%3d", p2); 38 left--; 39 } 40 status[p1] = 1; 41 status[p2] = 1; 42 if (left) //控制输出格式 43 printf(","); 44 } 45 printf("\n"); 46 } 47 return 0; 48 }
个性签名:时间会解决一切