1. 程式人生 > >列車排程(Train)習題精解與注意事項

列車排程(Train)習題精解與注意事項

題目: 

描述 某列車排程站的鐵道聯接結構如Figure 1所示。

其中,A為入口,B為出口,S為中轉盲端。所有鐵道均為單軌單向式:列車行駛的方向只能是從A到S,再從S到B;另外,不允許超車。因為車廂可在S中駐留,所以它們從B端駛出的次序,可能與從A端駛入的次序不同。不過S的容量有限,同時駐留的車廂不得超過m節。

設某列車由編號依次為{1, 2, ..., n}的n節車廂組成。排程員希望知道,按照以上交通規則,這些車廂能否以{a1, a2, ..., an}的次序,重新排列後從B端駛出。如果可行,應該以怎樣

的次序操作?

輸入 共兩行。

第一行為兩個整數n,m。

第二行為以空格分隔的n個整數,保證為{1, 2, ..., n}的一個排列,表示待判斷可行性的駛出序列{a1,a2,...,an}。

輸出 若駛出序列可行,則輸出操作序列,其中push表示車廂從A進入S,pop表示車廂從S進入B,每個操作佔一行。

若不可行,則輸出No。

樣例 Example 1 Input

5 2 1 2 3 5 4 Output

push pop push pop push pop push push pop pop Example 2 Input

5 5 3 1 2 4 5 Output

No

限制 1 ≤ n ≤ 1,600,000

0 ≤ m ≤ 1,600,000

時間:2 sec

空間:256 MB

思路:使用一維陣列和int型別的指標模擬棧的基本操作,再設另一變數i作為入棧序列1,2,...n中的任意一個並不斷自增,若i不大於出棧序列out中的元素t,則入棧並判定棧是否空(m=0的情況),若空則out不可行。若i>t,則若判定棧非空且棧頂元素為t,出棧,反之out不可行。再定義一個一維陣列,元素為0為pop,1為push,時刻“記錄”每次出棧或入棧的操作,最後根據可行標誌輸出。注意:運算元最多為輸入數的2倍。

#include<cstdio>
#define MAXSIZE 1600001
int stack[MAXSIZE],op[2*MAXSIZE];//定義棧和標記操作的陣列,注意全域性陣列元素為0 
int i=1,j,k=0,m,n,t,flag=1,top=-1;//i為1,2,...n,k為陣列下標,flag標識序列可行性 
void Judge(){
	if(top!=-1&&stack[top]==t){//若棧非空且棧頂元素為t 
		top--;//出棧 
		k++;
	}
	else flag=0;
}
int main(){
	scanf("%d%d",&n,&m);
	while(n--){
		if(!flag)break;
		scanf("%d",&t);
		if(i<=t){//說明t未入棧,需要入棧 
			for(;top<m-1&&i<=t;i++)//將i到t入棧,注意top從-1開始,故top需小於m-1 
			{
				stack[++top]=i;//入棧 
				op[k++]=1;//1為push,0為pop 
			}
			Judge();
		}
		else Judge();
	}
	if(flag){//若序列可行,輸出 
		for(i=0;i<k;i++)
		if(op[i])
		puts("push");
		else
		puts("pop");
	}
	else 
	puts("No");
	return 0;
}