杭電1276士兵隊列的訓練問題
本來這題想用直接的模擬法去解答,但一看數據爲5000,也還是可以,可是模擬是用數組的話無法直接去掉被刪除的元素,用鏈表可以完全模擬,但是鏈表操作比較麻煩,想盡量避免鏈表操作的使用。所以本題就想到了用兩個鏈表來回操作來進行模擬。
首先定義兩個數組s1,s2。s1先存儲所有士兵的編號,然後由於依次報到2的士兵都會被出列,數組下標與編號對應,這樣就可以把數組下標爲奇數的元素轉到s2,從下標爲1連續存儲。再依次報到3,士兵出列,再把在數組s2中下標模3不等於0的元素轉移到s1中。下標爲1依次存儲。這樣來回轉換,利用變量K依次記錄轉換後還剩下的元素個數,這樣來回轉換,知道K<=3時停止,對數組s1,或者s2中的元素進行輸出
ps:注意士兵數量n<=3的情況,直接對數組元素進行輸出。
注意兩個輸出編號之間的空格。
AC代碼:
首先定義兩個數組s1,s2。s1先存儲所有士兵的編號,然後由於依次報到2的士兵都會被出列,數組下標與編號對應,這樣就可以把數組下標爲奇數的元素轉到s2,從下標爲1連續存儲。再依次報到3,士兵出列,再把在數組s2中下標模3不等於0的元素轉移到s1中。下標爲1依次存儲。這樣來回轉換,利用變量K依次記錄轉換後還剩下的元素個數,這樣來回轉換,知道K<=3時停止,對數組s1,或者s2中的元素進行輸出
ps:注意士兵數量n<=3的情況,直接對數組元素進行輸出。
注意兩個輸出編號之間的空格。
AC代碼:
#include<iostream>
using namespace std;
int main()
{
int st[6000];
int oz[6000];
int n;
cin>>n;
while(n--)
{
int t;
int i,j,k;
cin>>t;
if(t<=3)
{
for(int i=1;i<t;i++)
{
cout<<i<<' ';
}
cout<<t<<endl;
}
else
{
int flag=0;
for(i=1;i<=t;i++)
{
st[i]=i;
}
while(t>3)
{
j=1;
for( i=1;i<=t;i+=2)
{
oz[j++]=st[i];
}
//t=(t+1)>>1;
t=j-1;
if(t<=3)
{
flag=1;
break;
}
k=1;
for(i=1;i<=t;i++)
{
if(i%3!=0)
{
st[k++]=oz[i];
}
}
t=k-1;
if(t<=3)
{
flag=2;
break;
}
}
if(flag==1)
{
for(i=1;i<t;i++)
{
cout<<oz[i]<<' ';
}
cout<<oz[t]<<endl;
}
if(flag==2)
{
for(i=1;i<t;i++)
{
cout<<st[i]<<' ';
}
cout<<st[t]<<endl;
}
}
}
return 0;
}