2017/7/17
二:
士兵队列训练问题
Input本题有多个测试数据组,第一行为组数N,接着为N行新兵人数,新兵人数不超过5000。
Output共有N行,分别对应输入的新兵人数,每行输出剩下的新兵最初的编号,编号之间有一个空格。
Sample Input
2 20 40
Sample Output
1 7 19 1 19 37
分析:报到2,报到3分别表示可以被2,3整除,刚开始以为是数字中包含2,3.要剔除2,3,然后重排,最后要输出原来的编号。
思路:用三个数组来储存
用a[i]来代表最初的数据,其实数组的下标i就是原来的编号
用b[i]代表是否是2,3的因子,是储存为1,否储存为0
用两个变量来储存总人数
n代表最开始的人数
t代表实时的人数(变化的)
最后吧b[i]==1的赋值给d[i]
源代码:
#include <iostream>
using namespace std;
#include <stdio.h>
#include <math.h>
int a[5001],b[5001];
int main()
{
int T,n,i,j,k,t,d[4];
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
//n=T;
for(i=1;i<=n;i++)//i表示最初的编号
{
a[i]=i;//初始化排队
b[i]=1;//全部初始化为1
}
t=n;//因为这里面的n会在计算中发生变化,所以要重新赋值,用另一个变量代替它发生变换!
if(n>3)//当n>3的时候,因为需要出列,所以按照题意执行就可以了,记住,执行过之后
for(j=1;j<=n;j++)//士兵的顺序不发生改变,但是序号值发生了变化!,所以在他们每出列一次要重新
{
for(i=1,k=0;i<=n;i++)//给士兵进行赋值操作!但是最后需要输出原来的数组编号!
{
if(a[i]%2==0&&b[i])//这并不难,因为标记数组的下标你又没有发生改变,所以到时候将数组b中对应是1的元素的下标输出来就行了!
{
b[i]=0;//把符合条件的赋值为0
t--;
}
else if(b[i])//把不被整除的重新编号
{
k++;
a[i]=k;
}
}
if(t<=3)//t==n,人数小于3直接输出
break;
for(i=1,k=0;i<=n;i++)
{
if(a[i]%3==0&&b[i])
{
b[i]=0;
t--;
}
else if(b[i])
{
k++;
a[i]=k;
}
}
if(t<=3)
break;
}
for(i=1,j=0;i<=n;i++)//因为题上格式要求比较严格,所以我们要进行赋值到一个数组中,进行
{
if(b[i])//比较规格的输出!
d[j++]=i;//j比i小1
}
if(t==3)
printf("%d %d %d\n",d[0],d[1],d[2]);
else if(t==2)
printf("%d %d\n",d[0],d[1]);
else if(t==1)
printf("%d\n",d[0]);
}
return 0;
}