1. 程式人生 > 其它 >AcWing第4場周賽題解

AcWing第4場周賽題解

A. AcWing 3694. A還是B

題目連結:https://www.acwing.com/problem/content/3697/

題目大意:判斷字串中'A'還是'B'出現地多。

解題思路:迴圈一遍記個數。

示例程式:

#include <bits/stdc++.h>
using namespace std;

string s;
int n, a, b;

int main() {
    cin >> n >> s;
    for (auto c : s)
        (c == 'A') ? a++ : b++;
    if (a == b) puts("T");
    else if (a > b) puts("A");
    else puts("B");
    return 0;
}

AcWing 3695. 擴充序列

題目連結:https://www.acwing.com/problem/content/3698/

題目大意:求序列擴充n次的第k個數。

解題思路:可以基於分治用遞迴做,也可以用二進位制做。因為這道題是cf原題,我遞迴寫過了,所以這裡用二進位制做,但其實都是基於分治思想。

示例程式:

#include <bits/stdc++.h>
using namespace std;

int n;
long long k;

int main() {
    cin >> n >> k;
    for (int i = n-1; i >= 0; i--) {
        if (!(k ^ (1LL<<i))) {
            cout << i+1 << endl;
            break;
        }
        k &= (1LL<<i)-1;
    }
    return 0;
}

C. AcWing 3696. 構造有向無環圖

題目連結:https://www.acwing.com/problem/content/3699/

題目大意:給圖上一些邊確定方向,使其成為一個 DAG。

解題思路:拓撲排序兩次,第一次給每個節點一個時間戳,然後根據時間戳的大小(小的往大的連一條邊),第二次(連好邊後)看看能不能正常拓撲排序,可以的話就 “YES”;不然就 “NO”。

示例程式:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;

int T, n, m, t[maxn], x[maxn], y[maxn], in[maxn], tt[maxn]; // tt[i]表示節點i的時間戳
vector<int> g[maxn];
queue<int> que;

bool check() {
    int idx = 0;    // 時間戳
    while (!que.empty()) que.pop();
    for (int i = 1; i <= n; i++) if (!in[i]) {
        tt[i] = ++idx;
        que.push(i);
    }
    while (!que.empty()) {
        int u = que.front();
        que.pop();
        for (auto v : g[u]) {
            in[v]--;
            if (!in[v]) {
                tt[v] = ++idx;
                que.push(v);
            }
        }
    }
    return idx == n;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> T;
    while (T--) {
        cin >> n >> m;
        for (int i = 0; i < m; i++)
            cin >> t[i] >> x[i] >> y[i];
        // 1-st topological sorting
        for (int i = 1; i <= n; i++) g[i].clear(), in[i] = 0;
        for (int i = 0; i < m; i++)
            if (t[i]) g[x[i]].push_back(y[i]), in[y[i]]++;
        if (!check()) {
            cout << "NO" << endl;
            continue;
        }
        // 根據原來的有向邊及時間戳重新建圖
        for (int i = 1; i <= n; i++)
            g[i].clear();
        for (int i = 0; i < m; i++) {
            int u = x[i], v = y[i];
            if (!t[i] && tt[u] > tt[v]) swap(u, v);
            g[u].push_back(v);
            in[v]++;
        }
        // 2-st topological sorting
        if (!check()) {
            cout << "NO" << endl;
        } else {
            cout << "YES" << endl;
            // 輸出邊的資訊
            for (int i = 0; i < m; i++) {
                int u = x[i], v = y[i];
                if (!t[i] && tt[u] > tt[v]) swap(u, v);
                cout << u << " " << v << endl;
            }
        }
    }
    return 0;
}