AtCoder Beginner Contest 361)

推荐个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";
    }
}
posted @ 2024-07-07 09:25  _Yxc  阅读(41)  评论(0编辑  收藏  举报