毅力號拍到高清火星環境圖,神似戈壁灘
比賽連結:https://atcoder.jp/contests/abc205
A - kcal
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(15); double a, b; cin >> a >> b; cout << a * b / 100 << "\n"; return 0; }
B - Permutation Check
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin >> n; vector<bool> have(n); for (int i = 0; i < n; i++) { int x; cin >> x; --x; have[x] = true; } cout << (count(have.begin(), have.end(), true) == n ? "Yes" : "No") << "\n"; return 0; }
C - POW
#include <bits/stdc++.h> using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int a, b, c; cin >> a >> b >> c; auto cal = [](int a, int b) { return a > b ? '>' : (a == b ? '=' : '<'); }; cout << (c % 2 == 0 ? cal(abs(a), abs(b)) : cal(a, b)) << "\n"; return 0; }
D - Kth Excluded
題意
從小到大給出 \(n\) 個正整數,問這些數外的第 \(k\) 大正整數。
題解
計算第 \(i\) 個數對當前位最小值 \(i\) 的溢位情況,二分第一個溢位不小於 \(k\) 的位置,取前面的數及其溢位情況即可。
程式碼
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, q;
cin >> n >> q;
vector<long long> a(n + 1);
for (int i = 1; i <= n; i++) {
cin >> a[i];
}
vector<long long> exceed(n + 1);
for (int i = 1; i <= n; i++) {
exceed[i] = a[i] - i;
}
while (q--) {
long long k;
cin >> k;
int pos = lower_bound(exceed.begin(), exceed.end(), k) - exceed.begin();
cout << a[pos - 1] + (k - exceed[pos - 1]) << "\n";
}
return 0;
}
E - White and Black Balls
題意
有 \(n\) 個白球和 \(m\) 個黑球,現要將這些球排成一排,要求
- 在所有長度的字首中,白球的個數均不多於黑球 \(k\) 個
問有多少種排列方式。
題解
與 CF1536C 的思想類似,將球的新增視作平面上點的移動,不妨將白球看作縱座標 \(y\) ,黑球看作橫座標 \(x\) ,本題即從 \((0, 0)\) 到 \((m, n)\) 的移動過程,共有 \(C_{m + n}^{m}\) 種排列方式。
又有 \(y \le x + k\) ,即:
因為不合法的情況(路徑)一定會與 \(y = x + k + 1\) 有交點,不妨將 \((0, 0)\) 關於該直線對稱,得到點 \((- k - 1, k + 1)\) ,不合法的情況即轉化為從 \((- k - 1, k + 1)\) 移動到 \((m, n)\) 的情況,共有 \(C_{m + n}^{m + k + 1}\) 種情況。
綜上,除去一開始白球比黑球多 \(k\) 個無解的情況,答案為 \(C_{m + n}^{m} - C_{m + n}^{m + k + 1}\) 。
程式碼
#include <bits/stdc++.h>
using namespace std;
constexpr int N = 2e6 + 10;
constexpr int MOD = 1e9 + 7;
int fac[N], inv[N];
int binpow(int a, int b) {
int res = 1;
while (b) {
if (b & 1) res = 1LL * res * a % MOD;
a = 1LL * a * a % MOD;
b >>= 1;
}
return res;
}
int C(int n, int m){
if(m < 0 or m > n) return 0;
return 1LL * fac[n] * inv[m] % MOD * inv[n - m] % MOD;
}
void Init(){
fac[0] = 1;
for (int i = 1; i < N; i++) fac[i] = 1LL * fac[i - 1] * i % MOD;
inv[N - 1] = binpow(fac[N - 1], MOD - 2);
for (int i = N - 2; i >= 0; i--) inv[i] = 1LL * inv[i + 1] * (i + 1) % MOD;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
Init();
int n, m, k;
cin >> n >> m >> k;
if (n - m > k) {
cout << 0 << "\n";
} else {
cout << (C(m + n, m) - C(m + n, m + k + 1) + MOD) % MOD << "\n";
}
return 0;
}
F - Grid and Tokens
題意
給出一個 \(h \times w\) 的網格,有 \(n\) 個人,第 \(i\) 個人可以選擇 \(a_i \sim c_i\) 行 \(b_i \sim d_i\) 列中的某個網格,一個網格只能被一個人選擇,問最多有多少人可以都選到一個網格。
題解
將問題轉化為最大流問題,每個人可選擇一個網格即轉化為容量為 \(1\) 的邊 \((u_i, v_i)\) ,可選擇的行即轉化為 \(u_i\) 前的結點 \(r_{a_i \sim c_i}\) ,可選擇的列即轉化為 \(v_i\) 後的結點 \(c_{b_i \sim d_i}\) ,多人可選擇即轉化為 \(r_i\) 前的超級源點 \(src\) , \(c_i\) 後的超級匯點 \(dst\) ,兩者間的最大流即最多有多少人可以都選到一個網格。
程式碼
#include <bits/stdc++.h>
#include <atcoder/maxflow>
using namespace std;
using namespace atcoder;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int h, w, n;
cin >> h >> w >> n;
map<int, int> row, col, u, v;
for (int i = 0; i < h; i++) {
row[i] = i + 1;
}
for (int i = 0; i < w; i++) {
col[i] = i + 1 + h;
}
for (int i = 0; i < n; i++) {
u[i] = i + 1 + h + w;
}
for (int i = 0; i < n; i++) {
v[i] = i + 1 + h + w + n;
}
int src = 0, dst = h + w + 2 * n + 1;
mf_graph<int> graph(dst + 1);
for (int i = 0; i < h; i++) {
graph.add_edge(src, row[i], 1);
}
for (int i = 0; i < w; i++) {
graph.add_edge(col[i], dst, 1);
}
for (int i = 0; i < n; i++) {
int a, b, c, d;
cin >> a >> b >> c >> d;
--a, --b;
graph.add_edge(u[i], v[i], 1);
for (int j = a; j < c; j++) {
graph.add_edge(row[j], u[i], 1);
}
for (int j = b; j < d; j++) {
graph.add_edge(v[i], col[j], 1);
}
}
cout << graph.flow(src, dst) << "\n";
return 0;
}
參考
D:
https://atcoder.jp/contests/abc205/editorial/2079
E:
https://atcoder.jp/contests/abc205/editorial/2080
F:
https://atcoder.jp/contests/abc205/editorial/2081
https://codeforces.com/blog/entry/91733?#comment-803511
後記
三門大作業和一堆實驗終於都做完啦ヽ(✿゚▽゚)ノ
剩下的就只剩在充裕的時間裡複習準備期末考試了,好耶( ̄▽ ̄)
時間真是快啊,不知不覺學長學姐們都已經畢業了,祝學長學姐們學業有成,工作順利 ~
明年這個時候就該自己啦 ╰( ̄ω ̄o)