救济金发放 (The Dole Queue, UVa 133)

来源:互联网 发布:mac svn服务器地址 编辑:程序博客网 时间:2024/05/01 12:00

原题目:The Dole Queue
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

个人认为这个题目对于熟练使用%运算符非常的重要,比如本人第一个版本的虽然也能AC,但是代码可读性实在是太渣了.还是看大牛的代码提高快,脱离学习区,可以提高的更快.若让p1-5 循环可以p=(p+5)%5 + 1,也可以用p%5;p++ 还是要灵活运用,多总结.

#include <iostream>#include <stdio.h>using namespace std;int number[1000000];bool allZero(int number[], int n){    for (int i = 0; i <= n; i++)    {        if (number[i] != 0)        {            return false;        }    }    return true;}int move_start(int start, int k, int n){    while (k--)    {        do        {            start = (start + n) % n + 1;        } while (number[start] == 0);    }    return start;}int move_end(int end, int m, int n){    while (m--)    {        do        {            end = (end - 2 + n) % n + 1;        } while (number[end] == 0);    }    return end;}int main(){    int n, k, m;    while (scanf("%d%d%d", &n, &k, &m) == 3 && (n || k || m))    {        for (int i = 1; i <= n; i++)        {            number[i] = 1;        }        int start = 0, end = n + 1;        while (!allZero(number, n))        {            start = move_start(start, k, n);            end = move_end(end, m, n);            number[start] = 0;            number[end] = 0;            if (start == end)            {                printf("%3d", start);            } else            {                printf("%3d%3d", start, end);            }            if (!allZero(number, n))            {                cout << ",";            }        }        cout << endl;    }    return 0;}
0 0
原创粉丝点击