题意:為了縮短領救濟品的隊伍,NNGLRP決定了以下策略:每天所有來申請救濟品的人會被放在一個大圓圈,面朝裡面。選定一個人為編號 1 號,其他的就從那個人開始逆時針開始編號直到 N。一個官員一開始逆時針數,數 k 個申請者,然後另一個官員第 N 個始順時針方向數 m 個申請者,這兩個人就被送去再教育。如果兩個官員數的是同一個人,那個人則被送去從政,然後2個官員再在剩下的人裡面繼續選直到沒人剩下來,注意兩個被選中的人是同時走掉的,所以就有可能兩個官員選中一個人。
例子:sample input:10 4 3 sample output:4 8, 9 5, 3 1, 2 6, 10, 7
13 17 42 4 11, 10 1, 8 6, 13 7, 3, 5 12, 9 2
7 8 47 1 3, 5 7, 2 4, 6
0 0 0
分析:一道模拟题,用vis数组来标记该数有没有被选过,然后用两个循环,因为是同时发生,所以去掉以及输出的操作放在最后,要注意输出格式
#include<iostream>
#include<cstring>
using namespace std;
int N, k, m;
int arr[25];
int vis[25];
int main(){
while(cin>>N>>k>>m && N){
int num = 0; //num来表示一共去掉了几个数
for(int i = 1; i<=N; i++){
arr[i] = i;
vis[i] = 1;
}
int A = 0, B = N+1;
int A_num = 0, B_num = 0; //用来记录数了多少个
int flagA, flagB; //用来判断A和B是不是同一个数
while(num<N){
int temp = 0;
flagA = 0; flagB = 0;
for(;;){
A++;
if(A>N) A = 1;
if(vis[A]){
A_num++;
if(A_num == k){
flagA = 1;
A_num = 0;
num++;
printf("%3d", A);
temp = A;
break;
}
}
}
for(;;){
B--;
if(B<1) B = N;
if(vis[B]){
B_num++;
if(B_num == m){
flagB = 1;
B_num = 0;
num++;
if(temp!=B) printf("%3d", B);
break;
}
}
}
if(flagA && flagB && A==B) num--;
if(num<N) printf(",");
if(flagA) vis[A] = 0;
if(flagB) vis[B] = 0;
}
printf("\n");
}
return 0;
}