UVa 133 - 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.


#include <cstdio>
#include <cstdlib>

struct Person{
	struct Person *front;
	int value;
	struct Person *next;
};

Person *top, *end;
int n, k, m;
int nCase=0;

void solve()
{
	if(nCase)printf("\n");
	Person *left=top, *right=end;
	Person *left_last = left, *right_last=right;
	while(1)
	{
		for(int i=2; i <= k; i++)
		{
			left_last= left;
			left = left->next;
		}
		for(int j=2; j <= m; j++)
		{
			right_last = right;
			right=right->front;
		}
		if(left==right)
		{
			if(n==1){
				printf("%3d", left->value);
				break;
			}else{
				printf("%3d,", left->value);
				right_last->front = left_last;
				left_last->next = right_last;
				
		
				left = left->next;
				right = right->front;
				n--;
			}
		}else{
			printf("%3d",left->value);
			left_last->next = left->next;
			left->next->front = left_last;
			
			printf("%3d",right->value);
			right->front->next = right_last;
			right_last->front = right->front;

			n -=2;
			if(n==0) break;
			else printf(",");
			
			Person *l=left, *r=right;
			l = l->next;
			r = r->front;
			if(l==right)
				l = l->next;
			if(r==left)
				r = r->front;
			left = l;
			right = r;
		}
	}
}

void init()
{
	Person *p = (Person *)malloc(sizeof(Person));
	Person *pre=NULL;
	top = p; pre = p;
	p->front = NULL;
	p->next=NULL;
	p->value = 1;

	for(int i=2; i <= n; i++)
	{
		Person *person = (Person *)malloc(sizeof(Person));
		pre->next = person;
		person->front = pre;
		person->next = NULL;
		person->value = i;
		pre = pre->next;
	}
	pre->next = p;
	p->front = pre;
	end = pre;
}

int main()
{

//	freopen("in.txt","r",stdin);
	while(scanf("%d %d %d", &n, &k, &m)==3 &&
		n!=0 && k!=0 && m!= 0)
		{
			init();
			solve();
			nCase++;
		}

	return 0;
}

以上是我的代码,纯用双向链表来模拟实现,既复杂又没有AC......郁闷的是我找了一个晚上都不知道错在哪里.....伤心了之后,去网上看到别人写的这些代码,我当时就跪了......


#include <cstdio>  
#include <cstring>  
const int maxn = 22;  
  
int N;  
bool d[maxn];  
  
int cw(int pos, int k) {  
    int cnt = 0;  
    for ( ; cnt != k; pos++) {  
        if (pos == N) pos = 0;  
        if (d[pos]) cnt++;  
    }  
    return --pos;  
}  
  
int w(int pos, int m) {  
    int cnt = 0;  
    for (; cnt != m; pos--) {  
        if (pos == -1) pos = N - 1;  
        if (d[pos]) cnt++;  
    }  
    return ++pos;  
}  
int main() {  
    int k, m;  
    while (scanf("%d%d%d", &N, &k, &m) && N && k && m) {  
        memset(d, 1, N);  
        int tot = N, flag = 0, a = 0, b = N - 1;  
        while (tot) {  
            a = cw(a, k), b = w(b, m);  
            tot--;  
            if (flag) printf(",");  
            d[a] = d[b] = false;  
            flag = 1;  
            if (a == b)  
                printf("%3d", a + 1);  
            else {  
                printf("%3d%3d", a + 1, b + 1);  
                tot--;  
            }  
        }//while find out all  
        printf("\n");  
    }//while  
    return 0;  
}  


数组代替链表,布尔变量标记是否访问过............

尼玛,不活了!!!

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