1. 程式人生 > >C++ zoj1259 Rails

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;
}

執行結果: