士兵队列训练

题目链接: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\n",a[1],a[2],a[3]);

40         if(n==2)printf("%d %d\n",a[1],a[2]);

41         if(n==1)printf("%d\n",a[1]);

42     }

43     return 0;

44 }

 

你可能感兴趣的:(队列)