士兵队列训练

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=83498#problem/C

题意:

      将新兵从一开始按顺序依次编号,并排成一行横队,从头开始一至二报数,凡报到二的出列,剩下的靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的靠拢,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。 输出最初编号。

      案例:

      input

      2

      20

      40

      output

      1 7 19

      1 19 37

思路分析:

      循环进行,循环条件为n>3;

      每次循环先报二再报三,报二时记为偶数,则报三是为奇数,首先判断是报二,还是报三。

      报二时把不报二的数重新存到数组中,人数n=n-n/2;

      报三时把不报三的数重新存到数组中,人数n=n-n/3;

      判断剩下的人数n,输出数组中前个数。

源代码如下:

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 int main()
 5 {
 6     int N;
 7     cin>>N;
 8     while(N--)
 9     {
10         int n,s=1,a[5010],k,i;
11         cin>>n;
12         for(i=1;i<=n;i++)
13             a[i]=i;
14         while(n>3)
15         {
16             s++;
17             k=2;
18             if(s%2==0)               //报二
19             {
20                 for(i=3;i<=n;i++)
21                     if(i%2!=0)       //判断不报二的人,重新存入数组
22                     {
23                         a[k]=a[i];
24                         k++;
25                     }
26                 n=n-n/2;
27             }
28             else                   //报三
29             {
30                 for(i=2;i<=n;i++)
31                     if(i%3!=0)      //判断不报三人,重新存入数组
32                     {
33                         a[k]=a[i];
34                         k++;
35                     }
36             n=n-n/3;
37             }
38         }
39         if(n==3)printf("%d %d %d
",a[1],a[2],a[3]);
40         if(n==2)printf("%d %d
",a[1],a[2]);
41         if(n==1)printf("%d
",a[1]);
42     }
43     return 0;
44 }
原文地址:https://www.cnblogs.com/q-c-y/p/4668749.html