ZeroJudge B684: 狗狗遊戲

小圓養了一隻可愛的小黑狗,但由於一時想不到什麼特別的名字,因此就叫牠「CuteBlack Dog」,簡稱 CBD。CBD 非常聰明,可以認得阿拉伯數字,也因此得到小圓的鍾愛。

在小圓的細心照料之下,CBD 日漸發福,小圓眼見這樣事情不太妙,於是設計一個遊戲讓 CBD 在玩的時候可以順便運動。

小圓設計的遊戲是這樣的:他先準備了 N 張紙卡,上面依序寫著 1 至 N 的各個正整數,並將這些紙卡在地上亂序的由左到右排成一列。接著他讓 CBD 先由最左邊的紙卡跑到最右邊的紙卡,再從最右邊跑回最左邊,不斷折返,並規定途中只要遇到寫著目前所剩餘的紙卡中,數值最小的那張紙卡,就要將該紙卡叼走,否則不能把該紙卡叼走。

舉例來說,假設一開始共有 5 張卡片,由左而右依序為 1, 4, 2, 5, 3,則 CBD 第一次由左端跑到右端時,延路會叼走 1, 2, 3 三張紙卡,折返往左跑時會叼走 4,又折返往右跑時再把 5 叼走。

小圓想請你幫他算一下,給定一開始的紙卡排列方式,CBD 一共至少需要改變幾次方向才能把所有紙卡都叼走呢?

範例測資

範例輸入範例輸出
測試資料的輸入共有兩列。
第一列為正整數 N,表示紙卡的數量。
第二列包含 N 個正整數,以空白隔開,表示由左到右紙卡上所寫的數值,保證 1 至 N 都
會恰好出現一次。

請輸出一列,其中包含一個整數,為 CBD 折返 (改變方向) 的次數。
2
1 2
0
5
1 4 2 5 3
2
4
4 3 2 1
1
1
1
0

解題思路

將資料用 Pair 的方式收起來,第一個欄位是目前位置的數字,第二個欄位是這個數字的位置。將這些資料使用陣列收起來,並且進行排序。排序過後,將陣列從頭跑到尾,並且紀錄目前是往右走還是往左走,如果目前數字的位置是目前位置的反方向,則將答案 +1 且換方向。

範例程式碼-ZeroJudge B684: 狗狗遊戲

#include <iostream>
#include <algorithm>
using namespace std;

int main() {
    cin.sync_with_stdio(0);
    cin.tie(0);
    int N;
    cin >> N;
    pair<int, int> num[1000005] = {};
    for (int i = 0; i<N; i++) {
        int tmp;
        cin >> tmp;
        num[i] = make_pair(tmp, i);
    }
    sort(num, num+N);
    string sign = "Big";
    int position = 0, ans = 0;
    for (int i = 0; i<N; i++) {
        if (sign == "Big") {
            if (num[i].second >= position) position = num[i].second;
            else {
                ans++;
                sign = "Small";
                position = num[i].second;
            }
        }
        else {
            if (num[i].second < position) position = num[i].second;
            else {
                ans++;
                sign = "Big";
                position = num[i].second;
            }
        }
    }
    cout << ans << "\n";
}

//ZeroJudge B684
//Dr. SeanXD

發佈留言