AtCoder Beginner Contest 361)

_Yxc發表於2024-07-07

推薦個C++程式設計倉庫模板

https://github.com/yxc-s/programming-template

A - Insert

void solve() {
	int n, k, x;
	cin >> n >> k >> x;

	vector<int> a(n);
	for (auto& x : a){
		cin >> x;
	}
	a.insert(a.begin() + k, x);

	for (int i = 0; i < a.size(); ++i){
		cout << a[i] << " \n"[i == n];
	}
}

B Intersection of Cuboids

題意:給定空間中2個立方體,每個立方體用兩個三維的對角線座標表示。問兩個立方體是否相交。

思路:只要在任意一個維度上,某個立方體的終點<=另一個立方體的起點,則無解。

總結:一開始只考慮了一個立方體的每個維度上都在另一個立方體內部的情況,其實3個維度,不管哪個立方體滿足條件都可以。

void solve() {
    vector<array<int, 6>> a(2);
    for (int i = 0; i < 2; ++i){
        for (auto& x : a[i]){
            cin >> x;
        }
    }

    for (int i = 0; i < 3; ++i){
        if (a[0][i + 3] <= a[1][i] || a[1][i + 3] <= a[0][i]){
            cout << "No\n";
            return;
        }
    }

    cout << "Yes\n";
}

C - Make Them Narrow

題意:給定一個序列,刪除k個數後,讓序列中最大與最小值的差最小。

思路:排序後,檢查長度為(n - k)的滑動視窗中最左最右元素的差值最小值。

總結:一開始以為,以為要刪除k個數,讓序列組成的數最小和最大,然後求他們的差值,使用了一個next陣列,陣列中表示當前位置的下一個數[1~9]所在的位置是多少,依次檢查當前的數最有可能變成的數需要刪除多少個元素。。最後準備測試了發現讀錯題了。。

void solve() {
	int n, k;
	cin >> n >> k;

	vector<int> a(n);
	for (auto& x : a){
		cin >> x;
	}

	sort(a.begin(), a.end());

	int t = n - k - 1;
	int ans = INF;
	for (int i = 0; i + t < n; ++i){
		ans = min(ans, a[i + t] - a[i]);
	}

	cout << ans << endl;
}

D - Go Stone Puzzle

題意:搜尋問題

思路:直接搜就行

總結:不知道為什麼雙向bfs沒過,但是單向bfs過了??

void solve() {
    int n;
    string s, t;
    cin >> n >> s >> t;

    if (count(s.begin(), s.end(), 'W') != count(t.begin(), t.end(), 'W')){
        cout << "-1\n";
        return;
    }

    if (s == t){
        cout << "0\n";
        return;
    }

    s += "..";
    t += "..";
    unordered_set<string> sett{s};
    unordered_set<string> sett_r{t};
    auto bfs = [&](){
        queue<pair<string, int>> q;
        queue<pair<string, int>> qr;
        q.emplace(s, 0);
        qr.emplace(t, 0);
        while (!q.empty() || !qr.empty()){
            int step = q.front().second;
            while (!q.empty() && q.front().second <= step){
                auto[cur, cnt] = q.front();
                q.pop();
                int p = cur.find('.');
                for (int i = 0; i < n + 1; ++i){
                    if (abs(i - p) <= 1){
                        continue;
                    }
                    string tt = cur;
                    swap(tt[i], tt[p]);
                    swap(tt[i + 1], tt[p + 1]);
                    #if defined(double_search)
                    if (sett_r.count(tt)){
                        cout << 2 * cnt + 1 << '\n';
                        return true;
                    }
                    #else
                    if (tt == t){
                        cout << cnt + 1<< '\n';return true;
                    }
                    #endif
                    if (!sett.count(tt)){
                        sett.insert(tt);
                        q.emplace(tt, cnt + 1);
                    }
                }
            }
            #if defined(double_search)
            while (!qr.empty() && qr.front().second <= step){
                auto [cur, cnt] = qr.front();
                qr.pop();
                int p = cur.find('.');
                for (int i = 0; i < n + 1; ++i){
                    if (abs(i - p) <= 1){
                        continue;
                    }
                    string tt = cur;
                    swap(tt[i], tt[p]);
                    swap(tt[i + 1], tt[p + 1]);
                    if (sett.count(tt)){
                        cout << 2 * cnt + 2 << '\n';
                        return true;
                    }
                    if (!sett_r.count(tt)){
                        sett_r.insert(tt);
                        qr.emplace(tt, cnt + 1);
                    }
                }
            }
            #endif
        }

        return false;
    };

    if (!bfs()){
        cout << "-1\n";
    }
}

更新,雙向bfs已A,時間從50多ms降到6ms,tle的原因是第一個佇列可能已經空了,導致step計數錯了,但是第二個佇列還沒空,但是step是個垃圾值,所以導致一直迴圈。

#define double_search
void solve() {
    int n;
    string s, t;
    cin >> n >> s >> t;

    if (count(s.begin(), s.end(), 'W') != count(t.begin(), t.end(), 'W')){
        cout << "-1\n";
        return;
    }

    if (s == t){
        cout << "0\n";
        return;
    }

    s += "..";
    t += "..";
    unordered_set<string> sett{s};
    unordered_set<string> sett_r{t};
    auto bfs = [&](){
        queue<pair<string, int>> q;
        queue<pair<string, int>> qr;
        q.emplace(s, 0);
        qr.emplace(t, 0);
        while (!q.empty() || !qr.empty()){
            int step = q.front().second;
            while (!q.empty() && q.front().second <= step){
                auto[cur, cnt] = q.front();
                q.pop();
                int p = cur.find('.');
                for (int i = 0; i < n + 1; ++i){
                    if (abs(i - p) <= 1){
                        continue;
                    }
                    string tt = cur;
                    swap(tt[i], tt[p]);
                    swap(tt[i + 1], tt[p + 1]);
                    #if defined(double_search)
                    if (sett_r.count(tt)){
                        cout << 2 * cnt + 1 << '\n';
                        return true;
                    }
                    #else
                    if (tt == t){
                        cout << cnt + 1<< '\n';return true;
                    }
                    #endif
                    if (!sett.count(tt)){
                        sett.insert(tt);
                        q.emplace(tt, cnt + 1);
                    }
                }
            }
            #if defined(double_search)
            step = qr.front().second;
            while (!qr.empty() && qr.front().second <= step){
                auto [cur, cnt] = qr.front();
                qr.pop();
                int p = cur.find('.');
                for (int i = 0; i < n + 1; ++i){
                    if (abs(i - p) <= 1){
                        continue;
                    }
                    string tt = cur;
                    swap(tt[i], tt[p]);
                    swap(tt[i + 1], tt[p + 1]);
                    if (sett.count(tt)){
                        cout << 2 * cnt + 2 << '\n';
                        return true;
                    }
                    if (!sett_r.count(tt)){
                        sett_r.insert(tt);
                        qr.emplace(tt, cnt + 1);
                    }
                }
            }
            #endif
        }

        return false;
    };

    if (!bfs()){
        cout << "-1\n";
    }
}