题意:约瑟夫问题,从两头双向删人。N个人逆时针1~N,从1开始逆时针每数k个人出列,同时从n开始顺时针每数m个人出列.若数到同一个人,则只有一个人出列。输出每次出列的人,用逗号可开每次的数据。
题解:模拟。
技巧:将顺时针逆时针的模拟合并为同一个函数。
p1 = go(p1, 1, k);p2 = go(p2, -1, m); 循环处理:
do p = (p + d + n - 1) % n + 1; while (a[p] == 0); (int p1 = n, p2 = 1;) 别忘了
a[p1] = a[p2] = 0; left--
#include<iostream>
#include<iomanip>
using namespace std;
int n;
int a[];
int go(int p, int d, int t) {
while (t--) {
do p = (p + d + n - ) % n + ; while (a[p] == );
}
return p;
}
int main()
{ int k, m;
while (cin >> n >> k >> m) {
if (n == )break;
for (int i = ; i <= n; i++) {
a[i] = i;
}
int left = n;
int p1 = n, p2 = ;
while (left) {
p1 = go(p1, , k);
p2 = go(p2, -, m);
cout << setw() << a[p1]; left--;
if (p1 != p2)cout << setw() << a[p2], left--;
a[p1] = a[p2] = ;
if (left)cout << ','; }
cout << endl;
}
return ; }