AtCoder Beginner Contest 213【A - E】
阿新 • • 發佈:2021-08-09
比賽連結:https://atcoder.jp/contests/abc213/tasks
A - Bitwise Exclusive Or
題意
給出兩個值在 \([0, 255]\) 間的數 \(a,b\) ,找到一個非負數 \(c\) 使得 \(a \oplus c = b\) 。
題解
由異或的性質,輸出 \(a \oplus b\) 即可。
程式碼
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int a, b; cin >> a >> b; cout << (a ^ b) << "\n"; return 0; }
B - Booby Prize
題意
給出 \(n\) 個不同的數,輸出第二大的數的位置。
題解
模擬。
程式碼
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<int> a(n); for (auto& x : a) { cin >> x; } vector<int> p(n); iota(p.begin(), p.end(), 0); sort(p.begin(), p.end(), [&](int x, int y) { return a[x] > a[y]; }); cout << p[1] + 1 << "\n"; return 0; }
C - Reorder Cards
題意
給出 \(n\) 個平面上的點,輸出它們離散化後的相對行列位置。
題解
模擬。
程式碼
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int h, w, n; cin >> h >> w >> n; vector<int> a(n), b(n); for (int i = 0; i < n; i++) { cin >> a[i] >> b[i]; } map<int, int> row, col; auto my_unique = [&](vector<int> v, bool map_row) { sort(v.begin(), v.end()); v.resize(unique(v.begin(), v.end()) - v.begin()); for (int i = 0; i < (int)v.size(); i++) { (map_row ? row : col)[v[i]] = i; } }; my_unique(a, true); my_unique(b, false); for (int i = 0; i < n; i++) { cout << row[a[i]] + 1 << ' ' << col[b[i]] + 1 << "\n"; } return 0; }
D - Takahashi Tour
題意
給出一棵有 \(n\) 個結點的樹,從根節點 \(1\) 出發,每次優先遍歷序號較小的結點,如無結點可遍歷則返回上一結點,試模擬該過程。
題解
即模擬一次帶回溯的 \(dfs\) 過程。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
vector<set<int>> G(n);
for (int i = 0; i < n - 1; i++) {
int u, v;
cin >> u >> v;
--u, --v;
G[u].insert(v);
G[v].insert(u);
}
vector<int> path;
function<void(int, int)> dfs = [&](int u, int p) {
path.push_back(u);
for (auto v : G[u]) {
if (v != p) {
dfs(v, u);
if (G[u].size() >= 2 or u == 0) {
path.push_back(u);
}
}
}
};
dfs(0, -1);
for (auto i : path) {
cout << i + 1 << ' ';
}
return 0;
}
E - Stronger Takahashi
題意
給出一個 \(h \times w\) ,由 .
和 #
構成的網格,可以進行一種操作:
- 將一個 \(2 \times 2\) 的網格全變為
.
問從左上角走到右下角所需的最少操作次數。
題解
先模擬 \(0\) 花費的 \(bfs\) 過程,然後假設在當前點進行了操作,那麼與當前點哈密頓距離 \(\le 3\) 的點均視作 \(1\) 花費的可達點,優先佇列 \(bfs\) 即可。
程式碼
#include <bits/stdc++.h>
using namespace std;
const int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int h, w;
cin >> h >> w;
vector<string> MP(h);
for (auto& s : MP) {
cin >> s;
}
priority_queue<tuple<int, int, int>> pque;
vector<vector<bool>> vis(h, vector<bool> (w));
pque.emplace(0, 0, 0);
while (not pque.empty()) {
auto [d, x, y] = pque.top();
pque.pop();
d = -d;
if (vis[x][y]) {
continue;
}
vis[x][y] = true;
if (x == h - 1 and y == w - 1) {
cout << d << "\n";
break;
}
for (int i = 0; i < 4; i++) {
int nx = x + dir[i][0], ny = y + dir[i][1];
if (0 <= nx and nx < h and 0 <= ny and ny < w and not vis[nx][ny] and MP[nx][ny] == '.') {
pque.emplace(-d, nx, ny);
}
}
for (int dx = -2; dx <= 2; dx++) {
for (int dy = -2; dy <= 2; dy++) {
if (abs(dx * dy) == 4) {
continue;
}
int nx = x + dx, ny = y + dy;
if (0 <= nx and nx < h and 0 <= ny and ny < w) {
pque.emplace(-(d + 1), nx, ny);
}
}
}
}
return 0;
}