题意:约瑟夫问题,从两头双向删人。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[25]; int go(int p, int d, int t) { while (t--) { do p = (p + d + n - 1) % n + 1; while (a[p] == 0); } return p; } int main() { int k, m; while (cin >> n >> k >> m) { if (n == 0)break; for (int i = 1; i <= n; i++) { a[i] = i; } int left = n; int p1 = n, p2 = 1; while (left) { p1 = go(p1, 1, k); p2 = go(p2, -1, m); cout << setw(3) << a[p1]; left--; if (p1 != p2)cout << setw(3) << a[p2], left--; a[p1] = a[p2] = 0; if (left)cout << ','; } cout << endl; } return 0; }