1. 程式人生 > >演算法競賽 例4-3救濟金髮放(The Dole Queue,UVa 133)

演算法競賽 例4-3救濟金髮放(The Dole Queue,UVa 133)

n(n<20)個人站成一圈,逆時針編號為1~n。有兩個官員,A從1開始逆時針數,B從n開始順時針數。在每一輪中,官員A數k個就停下來,官員B數m個就停下來(注意有可能兩個官員停在同一個人上)。接下來被官員選中的人(1個或者2個)離開隊伍。
輸入n,k,m輸出每輪裡被選中的人的編號(如果有兩個人,先輸出被A選中的)。例如,n=10,k=4,m=3,輸出為4 8, 9 5, 3 1, 2 6, 10, 7。注意:輸出的每個數應當恰好佔3列。
輸入:
10 4 3
輸出:
_ _ 4_ _ 8,_ _ 9_ _ 5,_ _ 3_ _ 1,_ _ 2_ _ 6,_ 10,_ _ 7

本題在做的過程中未注意到逆時針編號。
順逆時針問題需要增加一個取指為1,-1的變數
將出陣列的元素設為0,用do{}while(a[i]==0)跳過值為0的元素

//
//  main.c
//  救濟金髮放
//
//  Created by 趙海博 on 2018/1/27.
//  Copyright © 2018年 趙海博. All rights reserved.
//
//

#include<stdio.h>
#include<string.h>
#define LOCAL
#define maxn 1000
int a[maxn];
int left;
int n,k,m;//A每次數k個,B每次數m個
int go(int p,int d,int t) { while(t--) { do { p = (p+n+d-1) % n +1; }while(a[p] == 0); } return p; } int main() { #ifdef LOCAL freopen("/Users/zhaohaibo/Desktop/a.txt","r",stdin); #endif //輸入 //初始化 //每次(判斷還有沒有人) //分別go //go完了輸出、把人從數組裡減掉
while(scanf("%d%d%d",&n,&k,&m)==3 && n) { for(int i=1;i<=n;i++) a[i] = i; left = n; int p1 = n,p2 = 1;//p1是A的指標,p2是B的指標 while(left) { p1 = go(p1,1,k); p2 = go(p2,-1,m); printf("%3d",p1); left--; if(p1 != p2) { printf("%3d",p2); left--; } a[p1] = a[p2] = 0; if(left) printf(","); } printf("\n"); } return 0; }