1. 程式人生 > >2017/7/17

2017/7/17

spa [1] style 執行 比較 class 個數 turn 空格

二:

士兵隊列訓練問題

某部隊進行新兵隊列訓練,將新兵從一開始按順序依次編號,並排成一行橫隊,訓練的規則如下:從頭開始一至二報數,凡報到二的出列,剩下的向小序號方向靠攏,再從頭開始進行一至三報數,凡報到三的出列,剩下的向小序號方向靠攏,繼續從頭開始進行一至二報數。。。,以後從頭開始輪流進行一至二報數、一至三報數直到剩下的人數不超過三人為止。

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;//ji1

}

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