AcWing第4場周賽題解
阿新 • • 發佈:2022-04-07
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; }