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;//全部初始化為
}
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[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;
}
2017/7/17