C++ zoj1259 Rails
題目:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1259
一、題目大意:
A中列車的原始列車序列為:1 2 3 … N,B中儲存列車的目標序列,問B中給出的列車目標序列是否可以將A中的原始序列通過中轉站station實現。A中的數進station了,就不可以返回到A中。
二、輸入輸出
輸入:
輸入由行塊組成。 除了最後一個之外的每個塊(其實就是每一行)都是描述了一個列車的可能重組要求(就是目標序列)。 在塊的第一行中,儲存著如上述中的整數N。在接下來的每一行中是由1,2, 3 … N 組成的序列(目標序列)。塊的最後一行僅包含0。(該次結束)
最後一個塊只包含一行,就是0。(表示整個程式結束)
5 -> 第一組測試資料: N=5
1 2 3 4 5 -> 這個目標序列可以實現,所以輸出"Yes"
5 4 1 2 3 -> 這個目標序列不可以實現,所以輸出"No"
0 -> 第一組測試資料結束
6 -> 表示第二組測試資料塊: N=6
6 5 4 3 2 1 -> 這個目標序列可以實現,所以輸出"Yes"
0 -> 第二組測試資料結束
0 -> 表示測試完畢,整個程式結束
輸出:
目標序列是否可以實現的結果
注意:輸出每一個塊測試資料的結果完之後要空一行(N=5),接著輸出另一個塊(N=6)的的結果。
三、實現思路:用棧
重點是抓住目標序列
(1)判斷B中(目標序列)當前的數target[i]的數是否等於A中的數(j)?
如果是,則B和A都要往後移一個數,將i和j都加1;
如果不是,說明此時B中的數和A中的數不等;
(2)如果此時B中的數(target[i])和A中的數[j]不等:
是否可以在station中找到B中要的數(棧頂的數和target[i]是否相等)?
如果是,就把棧頂的數pop掉,同時B中的數往後移一個數(i++)
如果不是,那就要把A中數壓入到棧中,再去判斷B中此時的數和A中的數是否相等,如果還不相等,
就繼續壓入到棧中,直到A中沒有數了。
四、實現程式
#include <iostream>
#include <stack>
using namespace std;
const int MAXN = 1000;
int main()
{
int i, j, n, target[MAXN]; // arr陣列儲存目標序列(B中的資料)
stack <int> st;
while (cin >> n && n) // 如果n等於0,程式結束
{
while (cin >> target[0] && target[0]) //如果target[0]等於0表示當前塊的測試結束
{
// 輸入目標序列
for (i = 1; i < n; i++)
cin >> target[i];
j = 1; // 儲存A中的原始數列1,2... N,因為每次自增1,所以用j就行了,不用陣列
i = 0;
while (i < n)
{
if (j == target[i]) // 如果目標序列當前的數和j相等(即B中此時的數和A中的數相等)
{ // 那麼A和B都往後移一個數
j++;
i++;
}
else // B中的數和A中的數此時不等
{
// 判斷station中上面的數(最後進去的)是否等於目標序列
if (!st.empty() && target[i] == st.top())
{ // 如果相等,就把棧中(station)的數pop掉
st.pop();
i++; // 目標序列往後移一個數
}
else // 如果A和station中的數此時都不等於B中的數,那就把A中的數壓入到station(棧)中
{
if (j <= n) { // 判斷A中的數是否全部已壓入到station中
st.push(j);
j++;
}
else
break;
}
}
}
if (i == n)
cout << "Yes" << endl;
else
cout << "No" << endl;
while (!st.empty())
st.pop(); // 釋放空間
}
cout << endl;
}
return 0;
}
執行結果: