HDU 1276 士兵队列训练问题(队列)

题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1276

题目:

士兵队列训练问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 8934    Accepted Submission(s): 3947


Problem Description
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。
 
Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
 
Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
 
Sample Input
2
20
40
 
Sample Output
1 7 19
1 19 37
 
思路:
报数问题,用队列处理。当前处理到的人必出队,如果不是报到2(或3)的人就再入队尾,反复操作,直到一轮结束,剩下的人不多于3个。注意!不是说不多于3个就立即停止报数,而是要报完一轮再判断。
 
代码:
 1 #include <cstdio>
 2 #include <queue>
 3 #include <vector>
 4 #include <algorithm>
 5 #include <iostream>
 6 using namespace std;
 7 queue<int>q;
 8 vector<int>v;
 9 void deal(int t){
10     int cur=1;
11     int num=q.size();
12     while (cur<num+1) {
13         int x=q.front();q.pop();
14         if(cur%t!=0)    q.push(x);
15         cur++;//报到t的人不再入队
16     }
17 }
18 int main(){
19     int t,n;
20     cin>>t;
21     while (t--) {
22         v.clear();
23         cin>>n;
24         for (int i=1; i<=n; i++)    q.push(i);//初始入队
25         while (q.size()>3){//轮流处理报数2和3
26             deal(2);
27             if(q.size()>3)  deal(3);//上一轮结束如果不多于3人则不继续
28         }
29         while (!q.empty()) {
30             v.push_back(q.front());//将剩余的人存入vector容器
31             q.pop();
32         }
33         sort(v.begin(), v.end());//因为反复出队入队,所以顺序乱了,再排序一下
34         cout<<v[0];
35         for (int i=1; i<v.size(); i++)  cout<<" "<<v[i];
36         puts("");
37     }
38     return 0;
39 }

 

posted @ 2017-07-18 16:50  ventricle  阅读(367)  评论(0编辑  收藏  举报