首页 > 代码库 > 16级第三周寒假作业E题

16级第三周寒假作业E题

兵队列训练问题

TimeLimit:1000MS  MemoryLimit:32768KB
64-bit integer IO format:%I64d
Problem Description

某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。(注意每轮报数都要全部报完,不是人数不大于3就停止报数)

Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
SampleInput
2
20
40
SampleOutput
1 7 19
1 19 37

思路:这个题第一次看起来我是 没什么思路的(抛弃旺神提示的队列),然后就开始想说用数组模拟,因为我们放进数组的时候本身就是有顺序的,但是处理的时候就有些复杂了,因为数组删除太麻烦;
所以就用队列模拟,在需要的时候把某个元素舍去,而且不打乱原来的顺序,打乱了?那你把队列循环一圈不就行了吗??因为有两种不同的处理方法,所以用一个变量标记一下第几次模拟编序号
放上我的代码,如果有什么不懂就看我的代码上面有注释
技术分享
 1 #include<stdio.h>
 2 #include<queue>
 3 using namespace std;
 4 int main()
 5 {
 6     int N,n;
 7     scanf("%d",&N);
 8     while(N--)
 9     {
10         queue<int>q;//这个应该都懂的,队列定义;
11         scanf("%d",&n);
12         for(int i=1;i<=n;i++)
13             q.push(i);//把每个人的编号按顺序压入队列
14         int p=1,x,k;
15         while(q.size()>3)////如果还有超过三个人,继续进行编号和排除等操作
16         {
17             x=q.size();////目前一共有多少人
18             if(p&1)//如果是第奇数次,那么就是从 1 到 2 编号
19             {
20                 for(int i=0;i<x/2;i++)//循环操作
21                 {
22                     k=q.front();//取出编号为1的
23                     q.push(k);//把编号为 1 的放后边,入队
24                     q.pop();////抛弃编号为 1 (已经放后面了,这个就不需要了)
25                     q.pop();//现在弹出的编号为 2 ,抛弃...
26                 }
27                 if(x&1)
28                 {
29                     k=q.front();//如果刚开始的时候为奇数个,那么最后还有一个人没被循环过....  
30                     q.push(k);//放队尾
31                     q.pop();//抛弃.
32                 }
33             }
34             else//第偶数次,那就是从 1 到 3 编号
35             {
36                 for(int i=0;i<x/3;i++)
37                 {
38                     k=q.front();//处理编号为 1 ,处理方式和前面一样
39                     q.push(k);
40                     q.pop();
41                     k=q.front();q.push(k);//处理编号为 2
42                     q.pop();
43                     q.pop();//抛弃编号为 3 的 
44                 }
45                 while(x%3!=0)//这里和前面的道理一样,防止有人未处理完
46                 {
47                     --x;
48                     k=q.front();//处理剩余的那几个
49                     q.push(k);
50                     q.pop();
51                 }
52             }
53             p++;
54         }
55         while(q.size()!=1)//输出
56         {
57             printf("%d ",q.front());
58             q.pop();
59         }
60         printf("%d\n",q.front());
61     }
62     return 0;
63 }
AC代码

 

16级第三周寒假作业E题