原题描述:
G - 士兵队列训练问题
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。
Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
Sample Input
2 20 40
Sample Output
1 7 19 1 19 37 我们这题的解题方法比较暴力,根据新兵人数来定义数组,每个元素都赋值他对应的编号。题目要我们先把报二的整数的人除去再把报三的人除去。按照这一循环直到三人,我们就可以给出一个循环。(每报一次数之后都要判断剩下是否低于三人)那如何判断他是报二的整数和报三的整数呢?我们用到了一个g值只要到二就把此值变为——1,下次不再报数然后g值清0.后面直接输出不等于-1的值。空格和换行的方法也很简单(要注意1号兵都会留到最后)AC代码:
1 #include <iostream> 2 using namespace std; 3 int main() 4 { 5 int t,n,k; 6 cin>>t; 7 while(t--) 8 { 9 cin>>n; 10 k=n; 11 if(n<=3) 12 { 13 cout<<"1"; 14 for(int i=2;i<=n;i++) 15 cout<<" "<<i; 16 cout<<endl; 17 continue; 18 } 19 int a[n+1]; 20 for(int i=1;i<=n;i++) 21 a[i]=i; 22 while(1) 23 { 24 int g=0; 25 for(int i=1;i<=n;i++) 26 { 27 if(a[i]!=-1) 28 g++; 29 if(g==2) 30 { 31 a[i]=-1; 32 g=0; 33 } 34 } 35 k=k-(k/2); 36 if(k<=3) 37 break; 38 g=0; 39 for(int i=1;i<=n;i++) 40 { 41 if(a[i]!=-1) 42 g++; 43 if(g==3) 44 { 45 a[i]=-1; 46 g=0; 47 } 48 } 49 k=k-(k/3); 50 if(k<=3) 51 break; 52 } 53 cout<<"1"; 54 for(int i=2;i<=n;i++) 55 { 56 if(a[i]!=-1) 57 cout<<" "<<a[i]; 58 } 59 cout<<endl; 60 } 61 return 0; 62 }
时间: 2024-11-06 12:04:33