1. 程式人生 > >1276 士兵佇列訓練問題【佇列模擬】

1276 士兵佇列訓練問題【佇列模擬】

士兵佇列訓練問題

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4565    Accepted Submission(s): 2128 Problem Description 某部隊進行新兵佇列訓練,將新兵從一開始按順序依次編號,並排成一行橫隊,訓練的規則如下:從頭開始一至二報數,凡報到二的出列,剩下的向小序號方向靠攏,再從頭開始進行一至三報數,凡報到三的出列,剩下的向小序號方向靠攏,繼續從頭開始進行一至二報數。。。,以後從頭開始輪流進行一至二報數、一至三報數直到剩下的人數不超過三人為止。

Input 本題有多個測試資料組,第一行為組數N,接著為N行新兵人數,新兵人數不超過5000。

Output 共有N行,分別對應輸入的新兵人數,每行輸出剩下的新兵最初的編號,編號之間有一個空格。

Sample Input 2 20 40
Sample Output 1 7 19 1 19 37

這個題剛看到的時候沒多少思路,如果用陣列模擬的話,應該可以實現,因為陣列本來就是有順序的,但是處理的時候就有些複雜了,因為陣列刪除太麻煩,

想想什麼型別的可以便於刪除和標記呢,好像沒有啊...尷尬

再拓展一下思路,發現一個好方法,完全可以用佇列模擬,在需要的時候把某個元素捨去,而且不打亂原來的順序,打亂了?那你把佇列迴圈一圈不就行了嗎??

因為有兩種不同的處理方法,所以用一個變數標記一下第幾次模擬編序號,因為兩種編號是交替的.......具體看程式碼註釋............

#include<stdio.h>
#include<queue>
using namespace std;
int main()
{
	int t,n,i,j;
	scanf("%d",&t);
	while(t--)
	{
		queue<int>q;//佇列定義,放在裡面是為了每次清空佇列
		scanf("%d",&n);
		for(i=1;i<=n;++i)
		{
			q.push(i);//把每個人的編號都按順序壓入佇列中
		}
		int p=1,x,k;
		while(q.size()>3)//如果還有超過三個人,繼續進行編號和排除等操作
		{
			x=q.size();//目前一共有多少人
			if(p&1)//如果是第奇數次,那麼就是從 1 到 2 編號 
			{
				for(i=0;i<x/2;++i)//迴圈操作
				{
					k=q.front();//<span style="font-family: Arial, Helvetica, sans-serif;">取出編號為 1 的</span>
					q.push(k);//把編號為 1 的放後邊,入隊
					q.pop();//拋棄編號為 1 (已經放後面了,這個就不需要了)
					q.pop();//現在彈出的編號為 2 ,拋棄...
				}
				if(x&1)
				{
					k=q.front();//如果剛開始的時候為奇數個,那麼最後還有一個人沒被迴圈過....
					q.push(k);//放隊尾
					q.pop();//拋棄.....
				}
			}
			else//第偶數次,那就是從 1 到 3 編號
			{
				for(i=0;i<x/3;++i)
				{
					k=q.front();q.push(k);//處理編號為 1 ,處理方式和前面一樣.....
					q.pop();
					k=q.front();q.push(k);//處理編號為 2 
					q.pop();
					q.pop();//拋棄編號為 3 的
				}
				while(x%3!=0)//這裡和前面的道理一樣,防止有人未處理完
				{
					--x;
					k=q.front();q.push(k);//處理剩餘的那幾個....
					q.pop();
				}	
			}
			++p;
		}
		while(q.size()!=1)//輸出,這樣是為了控制格式...
		{
			printf("%d ",q.front());
			q.pop();
		}
		printf("%d\n",q.front());	
	}
	return 0;
}

這個方法,就是完全模擬那個過程,只要考慮每次最後剩餘的那幾個人,其他就問題不大,這個自己手動模擬一下最好,能很快理解.........

也是第一次用 stl 裡面的佇列,感覺也是挺好用的,不過對於不理解那些 stl 裡面提供的資料結構或者函式的工作原理的話,儘量別用,先把那些模擬這些功能的方法給弄明白,否則就算自己用 stl 能做某些簡單的模板題,但是如果以後牽扯的多的時候,就可能因為自己對這些函式什麼的 的工作原理不太明白導致用的不夠好,

這樣是很致命的,就像有些人,如果迴圈都沒理解透徹,就去學什麼資料結構,根本就學的不紮實,自己的想法,感覺自己一定要把某些基礎東西弄紮實,否則以後相同的東西一變形就把握不住了.............

最重要的還是基礎......

個人觀點......至少可以自己留著看.....嘿嘿....