【紫书】uva133 The Dole Queue 参数偷懒技巧

题意:约瑟夫问题,从两头双向删人。N个人逆时针1~N,从1开始逆时针每数k个人出列,同时从n开始顺时针每数m个人出列.若数到同一个人,则只有一个人出列。输出每次出列的人,用逗号可开每次的数据。

题解:模拟。

   技巧:将顺时针逆时针的模拟合并为同一个函数。

       p1 = go(p1, 1, k);p2 = go(p2, -1, m);

      循环处理:
      do p = (p + d + n - 1) % n + 1; while (a[p] == 0);int p1 = n, p2 = 1;)

      别忘了
      a[p1] = a[p2] = 0;

      left--
 
#include<iostream>
#include<iomanip>
using namespace std;
int n;
int a[25];
int go(int p, int d, int t) {
    while (t--) {
        do p = (p + d + n - 1) % n + 1; while (a[p] == 0);
    }
    return p;
}
int main()
{
    
     
    int k, m;
    while (cin >> n >> k >> m) {
        if (n == 0)break;
        for (int i = 1; i <= n; i++) {
            a[i] = i;
        }
        int left = n;
        int p1 = n, p2 = 1;
        while (left) {
            p1 = go(p1, 1, k);
            p2 = go(p2, -1, m);
            cout << setw(3) << a[p1]; left--;
            if (p1 != p2)cout << setw(3) << a[p2], left--;
            a[p1] = a[p2] = 0;
            if (left)cout << ',';

        }
        cout << endl;
    }
    return 0;

}

 

posted @ 2018-03-05 20:44  SuuTTT  阅读(110)  评论(0编辑  收藏  举报