士兵队列训练问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2510 Accepted Submission(s): 1131
Problem Description
某部队进行新兵队列训练,将新兵从一开始按顺序依次编号,并排成一行横队,训练的规则如下:从头开始一至二报数,凡报到二的出列,剩下的向小序号方向靠拢,再从头开始进行一至三报数,凡报到三的出列,剩下的向小序号方向靠拢,继续从头开始进行一至二报数。。。,以后从头开始轮流进行一至二报数、一至三报数直到剩下的人数不超过三人为止。
Input
本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
Output
共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
Sample Input
2 20 40
Sample Output
1 7 19 1 19 37
简单模拟,这题我是用的数组,数组里面存士兵编号。然后当他报数要离开队伍是赋值为一个很大的数,说明他离开队伍了,然后对数据排一次序,删掉后面不要的人(如果是1、2报数,则删掉 n/2 个人,剩余 n-n/2 个人,如果是1、2、3报数,则删掉 n/3 个人,剩余 n-n/3 个人)。
代码如下:
#include <iostream>
#include <algorithm>
#define MAX 888888
using namespace std;
bool cmp(int a, int b)
{
return a < b;
}
//处理1、2报数
void two(int *man, int &num)
{
int i;
for(i = 0; i < num; i++)
{
if(i%2+1 == 2)
{
man[i] = MAX;
}
}
sort(man,man+num,cmp);
num = num - num/2;
}
//处理1、2、3报数
void three(int man[], int &num)
{
int i;
for(i = 0; i < num; i++)
{
if(i%3+1 == 3)
{
man[i] = MAX;
}
}
sort(man,man+num,cmp);
num = num - num/3;
}
int main()
{
int n,i,allnum,num;
int man[5010];
cin >> n;
while(n--)
{
cin >> allnum;//输入总人数
//初始化编号
for(i = 0; i < allnum; i++)
{
man[i] = i+1;
}
num = allnum;//当前剩余的人数num
while(num > 3)
{
two(man,num);
if(num <= 3)
{
break;
}
else
{
three(man,num);
}
}
printf("%d",man[0]);
for(i = 1; i < num; i++)
{
printf(" %d",man[i]);
}
printf("\n");
}
return 0;
}