报数游戏是这样的:有n我的围成一圈,按顺序从1到n编好号。从第一我的开始报数,报到m(m<n)的人退出圈子;下一我的从1开始报数,报到m的人退出圈子。如此下去,直到留下最后一我的。其中n是初始人数;m是游戏规定的退出位次(保证为小于n的正整数)。要求用队列结构完成。输出数字间以空格分隔,但结尾不能有多余空格。ios
5 3
3 1 5 2 4
5 6
看到这个题,想到是用STL set来作
下面是最开始的代码error!
#include <iostream> #include<set> using namespace std; int main() { set<int> s; int m, n; cin >> n >> m; if (m >= n) { cout << "error!"; return 0; } for (int i = 0; i < n; i++) { s.insert(i + 1); } set<int>::iterator it; it = s.begin(); int flag = 0; while (s.size() != 0) { for (int i = 1; i < m; i++) { if (!(it != s.end())) { it = s.begin(); } it++; } if (!(it != s.end())) { it = s.begin(); } if (flag == 0) { cout << *it; flag = 1; } else { cout << " " << *it; } int c = *it; s.erase(c); int j = 1; it = s.find((c + 1) % n); if (!(it != s.end())) { it = s.begin(); } } }
测试结果:测试
可是看这一句 it = s.find((c + 1) % n); 假设(c+1)%n在set中没有找到的话,返回给it的地址就是s.end() 可是假设c+1没找到后面还有c+2的话就会出错,因此我手写了一个测试点,n=8,m=3。spa
按照题目意思推理得出: 3 6 1 5 2 8 4 7code
可是按照我写的代码得出的结果是:3 6 1 5 7 8 2 4blog
因此改进版代码为:队列
#include <iostream> #include<set> using namespace std; int main() { set<int> s; int m, n; cin >> n >> m; if (m >= n) { cout << "error!"; return 0; } for (int i = 0; i < n; i++) { s.insert(i+1); } set<int>::iterator it; it = s.begin(); int flag = 0; while (s.size() != 0) { for (int i = 1; i < m; i++) { if (!(it != s.end())) { it = s.begin(); } it++; } if (!(it != s.end())) { it = s.begin(); } if (flag == 0) { cout << *it; flag = 1; } else { cout <<" "<< *it; } int c = *it; s.erase(c); int j = 1; while (1) { it = s.find((c + j) % n); if (it != s.end()) break; else j++; if (j == n) { break; it = s.end(); } } if (!(it != s.end())) { it = s.begin(); } } }
得出结果:3 6 1 5 2 8 4 7游戏
PTA提交结果:正确ci
同一个测试点两种代码给出的结果是不同的,而PTA上提交都是正确的,说明测试点没有考虑到n远大于m的状况it