The Dole Queue UVA133



 The Dole Queue 

In a serious attempt to downsize (reduce) the dole queue, The New National Green Labour Rhinoceros Party has decided on the following strategy. Every day all dole applicants will be placed in a large circle, facing inwards. Someone is arbitrarily chosen as number 1, and the rest are numbered counter-clockwise up to N (who will be standing on 1's left). Starting from 1 and moving counter-clockwise, one labour official counts off k applicants, while another official starts from N and moves clockwise, counting m applicants. The two who are chosen are then sent off for retraining; if both officials pick the same person she (he) is sent off to become a politician. Each official then starts counting again at the next available person and the process continues until no-one is left. Note that the two victims (sorry, trainees) leave the ring simultaneously, so it is possible for one official to count a person already selected by the other official.

Input

Write a program that will successively read in (in that order) the three numbers (N, k and m; k, m > 0, 0 < N < 20) and determine the order in which the applicants are sent off for retraining. Each set of three numbers will be on a separate line and the end of data will be signalled by three zeroes (0 0 0).

Output

For each triplet, output a single line of numbers specifying the order in which people are chosen. Each number should be in a field of 3 characters. For pairs of numbers list the person chosen by the counter-clockwise official first. Separate successive pairs (or singletons) by commas (but there should not be a trailing comma).

Sample input

10 4 3
0 0 0

Sample output

 4  8,  9  5,  3  1,  2  6,  10,  7

where  represents a space.


这道题是一个双向约瑟夫环问题, 我是用数组模拟的,首先用两个数组right1,left1记录结点的左右结点,并且用tag记录这个结点有没有被删掉,模拟的有点烂,不过总算通过了,边界条件要注意。。

#include<iostream>
#include<iomanip>
#include<cstring>

using namespace std;

int left1[25],right1[25];
int tag[25];

int main()
{
    int n,k,m;
    while(cin>>n>>k>>m&&(n||k||m))
    {
        int i,j,len=n,k1=1,m1=n;
        if(n==1){cout<<"  1"<<endl;continue;}
        memset(tag,1,sizeof(tag));
        memset(left1,0,sizeof(left1));
        memset(right1,0,sizeof(right1));
        left1[1]=n,right1[1]=2;
        if(n>1) left1[n]=n-1,right1[n]=1;
        for(i=2;i<n;i++)
        {
            left1[i]=i-1;
            right1[i]=i+1;
        }
        while(len>=1)
        {
            for(i=1;i<k;i++)
            {
                k1=right1[k1];
            }
            for(i=1;i<m;i++)
            {
                m1=left1[m1];
            }
            int l,r;
            if(m1!=k1&&len>1)
            {
                len=len-2;
                cout<<setw(3)<<k1<<setw(3)<<m1;
                if(len!=0) cout<<",";
                l=left1[k1];
                r=right1[k1];
                right1[l]=r;
                left1[r]=l;
                tag[k1]=0;
                tag[m1]=0;
                while(!tag[right1[k1]])
                {
                    if(len==0) break;
                    k1=right1[k1];
                }
                k1=right1[k1];
                l=left1[m1];
                r=right1[m1];
                right1[l]=r;
                left1[r]=l;
                while(!tag[left1[m1]])
                {
                    if(len==0) break;
                    m1=left1[m1];
                }
                m1=left1[m1];
            }
            else if(len>1&&m1==k1)
            {
                cout<<setw(3)<<m1<<",";
                len=len-1;
                l=left1[m1];
                r=right1[m1];
                right1[l]=r;
                left1[r]=l;
                tag[m1]=0;
                 while(!tag[right1[k1]])
                {
                    if(len==0) break;
                    k1=right1[k1];
                }
                k1=right1[k1];
                 while(!tag[left1[m1]])
                {
                    if(len==0) break;
                    m1=left1[m1];
                }
                m1=left1[m1];
            }
            else if(len==1&&m1==k1)
            {
                cout<<setw(3)<<k1;
                tag[k1]=0;
                break;
            }
        }
        cout<<endl;
    }
    return 0;
}

你可能感兴趣的:(C++,ACM,uva)