The Dole Queue
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;
}