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

来源:互联网 发布:管道支架计算软件 编辑:程序博客网 时间:2024/05/11 01:59

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

UVa Online Judge题目链接

  • 题目名称:救济金发放
  • 题目描述:
  • n(n < 20)个人站成一圈,逆时针编号为1~n,有两个官员,A从1开始逆时针数,B从n开始顺时针数,在每一轮中,官员A数k个就停下来,官员B数m个就停下来
  • (注意有可能两个官员停在同一个人身上)。接下来被官员选中的人(1个或者两个)离开队伍
  • 输入n,k,m输出每轮里被选中的人的编号,如果有两个人,先输出被A选中的,
  • 例如,n = 10;k = 4; m = 3 输出为4 8,9 5,3 1,2 6,10,7。 输出的每个数应当恰好占3列
  • 题目分析:
    • 题目分析:
  • ①用一个大小为0的数组表示人站成的圈
  • ②用0表示离开队伍的人,数数时候跳过就可以了。
  • ③这里最关键的问题就是如何统计官员AB数数选人的过程,所以这里考虑用两个p1、p2来指向他们的位置
  • ④顺时针和逆时针数数唯一的区别在于下标是加1还是减1,我们可以考虑把这两个过程融合到一个过程中,顺时针、逆时针我们看作一个+1/-1抽象为步长参数。
  • ⑤难点就在这里了,我们如何初始化p1、p2,怎么合理把他们融合起来p=(p+d+n-1)%n + 1 (这个很关键)
  • 循环过程:
  • 官员A:
    t = 4 -> p = 10 -> d = 1
    t = 3 -> p = 1 -> a[p] = 1
    t = 2 -> p = 2 -> a[p] = 2
    t = 1 -> p = 3 -> a[p] = 3
    t = 0 -> p = 4 -> a[p] = 4
    官员B:
    t = 3 -> p = 1 -> d = -1
    t = 2 -> p = 10 -> a[p] = 10
    t = 1 -> p = 9 -> a[p] = 9
    t = 0 -> p = 8 -> a[p] = 8
    官员A:
    t = 4 -> p = 4 -> d = 1
    t = 3 -> p = 5 -> a[p] = 5
    t = 2 -> p = 6 -> a[p] = 6
    t = 1 -> p = 7 -> a[p] = 7
    t = 0 -> p = 8 -> a[p] = 0 -> p = 9
  • ⑥这题还有一个关键点,就是输出格式的问题,因为每次循环情况有","隔开,最后一个没有逗号,所以我们要加一个变量left标示符,含义就是剩下的人数
  • ======================================================================================
  • 参考代码:
 //.cpp#include <iostream>#include <cstdio>using namespace std;const int maxn = 25;int n, k, m, a[maxn];//逆时针走t步,步长是d(-1表示顺时针走),返回新位置int go(int p, int d, int t){    while(t--)    {        do        {            p = (p + d + n -1)%n + 1;  //这个是难点,和初始化很有关系        }        while(a[p] == 0);  //走到下一个非0数字    }    return p;}int main(){    while(cin >> n >> k >> m && n)    {        //Init        int p1 = n, p2 = 1;        for(int i = 1; i <= n; i++)        {            a[i] = i;        }        int left = n; //剩余的人数        while(left)        {            p1 = go(p1, 1, k); //顺时针k            p2 = go(p2, -1, m); //逆时针m            printf("%3d", p1);            left--;            if(p2 != p1)            {                printf("%3d", p2);                left--;            }            a[p1] = a[p2] = 0; //直接把离开队伍的人位置置0            if(left)                printf(",");        }        printf("\n");    }    return 0;}
——To_捭阖_youth
0 0
原创粉丝点击