C. AtCoder AAC Contest
二分答案
代码实现
#include <bits/stdc++.h>
using namespace std;
void solve() {
int a, b, c;
cin >> a >> b >> c;
auto judge = [&](int x) {
if (a < x or c < x) return false;
int s = (a-x) + b + (c-x);
return s >= x;
};
int ac = 0, wa = a+1;
while (abs(ac-wa) > 1) {
int wj = (ac+wa)/2;
if (judge(wj)) ac = wj; else wa = wj;
}
cout << ac << '\n';
}
int main() {
int t;
cin >> t;
while (t--) solve();
return 0;
}
实际上答案就是 \(\min\{a, c, \lfloor\frac{a+b+c}{3}\rfloor\}\)
D. Least Unbalanced
分治
每次将当前值 \(x\) 分成两半,如果 \(x\) 为奇数,就将 \(\lfloor\frac{x}{x}\rfloor\) 放在左边,\(x- \lfloor\frac{x}{x}\rfloor\) 放在右边
这种构造可以保证平衡度最多为 \(1\)
当 \(k\) 是 \(2^n\) 的倍数时,最小平衡度为 \(0\),否则为 \(1\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, k;
cin >> n >> k;
vector<int> a(1, k);
rep(j, n) {
vector<int> na;
for (int x : a) {
na.push_back(x/2);
na.push_back(x-x/2);
}
a = na;
}
int u = 1;
if (k%a.size() == 0) u = 0;
cout << u << '\n';
for (int x : a) cout << x << ' ';
return 0;
}
E. Colinear
如果存在严格过 \(\frac{n}{2}\) 个的点,那么随机选两个点,它们都在这条直线上的概率至少是 \(\frac{1}{4}\),失败率最多为 \((1-\frac{1}{4})^{T}=(\frac{3}{4})^T\),尝试足够多的点对,失败概率极小
随机选两个点,不妨记为 \((x_1, y_1)\) 和 \((x_2, y_2)\)
\(ax_1 + by_1 + c = 0\)
\(ax_2 + by_2 + c = 0\)
\(\Rightarrow\) \((x_1-x_2)a = (y_2-y_1)b\)
那么我们只需取 \(a = y_2-y_1\),\(b = x_1-x_2\) 即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
struct V {
ll x, y;
};
int main() {
int n;
cin >> n;
vector<V> ps(n);
rep(i, n) cin >> ps[i].x >> ps[i].y;
rep(ti, 100) {
int i = rand()%n, j = rand()%(n-1);
if (i <= j) j++;
ll a = ps[j].y - ps[i].y;
ll b = ps[i].x - ps[j].x;
ll c = -(a*ps[i].x + b*ps[i].y);
int cnt = 0;
rep(k, n) {
if (a*ps[k].x + b*ps[k].y + c == 0) cnt++;
}
if (cnt*2 > n) {
puts("Yes");
cout << a << ' ' << b << ' ' << c << '\n';
return 0;
}
}
puts("No");
return 0;
}
F. Eat and Ride
最短路变种
记 dp[i][v] 表示从点 \(v\) 开始再走 \(i\) 步时所消耗的最少燃料
注意从后往前转移
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
inline void chmin(ll& a, ll b) { if (a > b) a = b; }
int main() {
int n, m;
cin >> n >> m;
vector<ll> w(n);
rep(i, n) cin >> w[i];
vector<vector<int>> to(n);
rep(i, m) {
int a, b;
cin >> a >> b;
--a; --b;
to[a].push_back(b);
to[b].push_back(a);
}
const ll INF = 1e18;
vector dp(n+1, vector<ll>(n, INF));
rep(i, n) dp[i][0] = w[0]*i;
for (int i = n-1; i >= 0; --i) {
rep(v, n) {
for (int u : to[v]) {
chmin(dp[i][u], dp[i+1][v] + w[u]*i);
}
}
}
rep(v, n) cout << dp[0][v] << '\n';
return 0;
}
G. Balls and Boxes
fps的入门题
第一题:ogf
\( F_a = 1 + x^A + x^{2A} + x^{3A} + \cdots \)
\( F_b = 1 + x^B + x^{2B} + x^{3B} + \cdots \)
\( F_c = 1 + x^C + x^{2C} + x^{3C} + \cdots \)
答案就是 \([x^N](F_aF_bF_c)\)
第二题:egf
\( F_a = \frac{1}{0!} \cdot 1 + \frac{1}{A!} \cdot x^A + \frac{1}{2A!} \cdot x^{2A} + \frac{1}{3A!} \cdot x^{3A} + \cdots \)
\( F_b = \frac{1}{0!} \cdot 1 + \frac{1}{B!} \cdot x^B + \frac{1}{2B!} \cdot x^{2B} + \frac{1}{3B!} \cdot x^{3B} + \cdots \)
\( F_c = \frac{1}{0!} \cdot 1 + \frac{1}{C!} \cdot x^C + \frac{1}{2C!} \cdot x^{2C} + \frac{1}{3C!} \cdot x^{3C} + \cdots \)
答案就是 \(N\)
代码实现
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace atcoder;
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using mint = modint998244353;
using fps = vector<mint>;
struct modinv {
int n; vector<mint> d;
modinv(): n(2), d({0,1}) {}
mint operator()(int i) {
while (n <= i) d.push_back(-d[mint::mod()%n]*(mint::mod()/n)), ++n;
return d[i];
}
mint operator[](int i) const { return d[i];}
} invs;
struct modfact {
int n; vector<mint> d;
modfact(): n(2), d({1,1}) {}
mint operator()(int i) {
while (n <= i) d.push_back(d.back()*n), ++n;
return d[i];
}
mint operator[](int i) const { return d[i];}
} facts;
struct modfactinv {
int n; vector<mint> d;
modfactinv(): n(2), d({1,1}) {}
mint operator()(int i) {
while (n <= i) d.push_back(d.back()*invs(n)), ++n;
return d[i];
}
mint operator[](int i) const { return d[i];}
} ifacts;
mint comb(int n, int k) {
if (n < k || k < 0) return 0;
return facts(n)*ifacts(k)*ifacts(n-k);
}
int main() {
int n;
cin >> n;
vector<int> a(3);
rep(i, 3) cin >> a[i];
rep(pid, 2) {
fps f = {1};
rep(i, 3) {
fps g(n+1);
for (int j = 0; j <= n; j += a[i]) g[j] = pid==0 ? 1 : ifacts(j);
f = convolution(f, g);
f.resize(n+1);
}
mint ans = f[n] * (pid==0 ? 1 : facts(n));
cout << ans.val() << '\n';
}
return 0;
}
浙公网安备 33010602011771号