Codeforces Round #677 (Div. 3)
A
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; m = n; k = 0;
while (m) ++k, m /= 10;
cout << (n % 10 - 1) * 10 + (1 + k) * (k) / 2 << '\n';
}
return 0;
}
B
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; k = m = 0;
rep (i, 1, n) {
cin >> a[i];
if (a[i] == 1 && a[i - 1] == 0) k += (m ? i - m - 1 : 0);
else if (a[i] == 0 && a[i - 1] == 1) m = i - 1;
}
cout << k << '\n';
}
return 0;
}
C
反正最后要吃最大值, 那不如直接让最大值升一级, 就可以全吃
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; VI a(n); k = -1;
for (auto &i : a) cin >> i;
m = *max_element(all(a));
rep (i, 0, n - 1) if (a[i] == m && ((i && a[i - 1] != m) || (i + 1 < n && a[i + 1] != m))) k = i + 1;
cout << k << '\n';
}
return 0;
}
D
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n; VI a(n + 1);
vector<VI> e; vector<VI> r;
unordered_map<int, int> st;
rep (i, 1, n) {
cin >> a[i];
if (!st.count(a[i])) st[a[i]] = e.size(), e.pb(VI(1, i));
else e[st[a[i]]].pb(i);
}
if (e.size() < 2) { cout << "NO\n"; continue; }
else cout << "YES\n";
rep (i, 0, e.size() - 2) for (auto j : e[i]) cout << j << ' ' << e[i + 1][0] << '\n';
rep (i, 1, e.back().size() - 1) cout << e.back()[i] << ' ' << e[0][0] << '\n';
}
return 0;
}
E
组合数学 首先是对称的, 随意选人要 / 2, \(C_n^{\frac{n}{2}} / 2\)
环内全排列, 因为循环可以重复, 所以 / n, 也就是$ sqr(A_{n/2}^{n/2} / n) = sqr(A_{n/2-1}^{n/2-1})$
然后我的 C 递推是减半的, 没除2
ll c[21][21], fac[21];
void init(int n) {
c[1][1] = fac[1] = fac[0] = 1;
rep (i, 2, n) fac[i] = fac[i - 1] * i;
rep (i, 2, n) rep (j, 1, i) c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
}
int main() {
IOS; init(20);
cin >> n; cout << c[n][n/2] << '\n';
cout << c[n][n / 2] * sqr(fac[n / 2 - 1]);
return 0;
}
F
dp就完事了
int main() {
IOS; cin >> n >> m >> k;
memset(f, -1, sizeof f); f[1][0][0] = 0;
rep(i, 1, n) {
rep(j, 1, m) {
cin >> a[i][j];
per(p, k - 1, 0)
per(q, min(m >> 1, j), 1) {
if (f[j & 1][((p - a[i][j]) % k + k) % k][q - 1] > -1)
umax(f[j & 1 ^ 1][p][q], f[j & 1][((p - a[i][j]) % k + k) % k][q - 1] + a[i][j]);
}
per(p, k - 1, 0)
per(q, min(m >> 1, j), 0) {
umax(f[j & 1 ^ 1][p][q], f[j & 1][p][q]);
}
}
rep(p, 0, k - 1)
rep(q, 1, m >> 1)
umax(f[1][p][0], max(f[1][p][q], f[0][p][q])), f[0][p][q] = f[1][p][q] = -1;
}
cout << f[1][0][0] << '\n';
return 0;
}
G
n*nlogn, 跑迪杰斯特拉
线性去判断每条边变成0 的答案
int main() {
IOS; cin >> n >> m >> k; vector<PII> ed;
vector<vector<PII>> h(n + 1); vector<PII> e;
rep (i, 1, m) {
int u, v, c; cin >> u >> v >> c;
e.pb({u, v}); h[u].pb({v, c}); h[v].pb({u, c});
}
rep (i, 1, k) {
int u, v; cin >> u >> v;
ed.pb({u, v});
}
vector<vector<ll>> d(n + 1, vector<ll>(n + 1, 1ll << 60));
rep (s, 1, n) {
priority_queue<PII> q; d[s][s] = 0;
q.push({0, s});
while (!q.empty()) {
PII p = q.top(); q.pop();
if (d[s][p.se] != -p.fi) continue;
for (auto &y : h[p.se]) {
int w = d[s][p.se] + y.se;
if (w >= d[s][y.fi]) continue;
d[s][y.fi] = w; q.push({ -w, y.fi});
}
}
}
ll ans = 1ll << 62;
for (auto g : e) {
ll tmp = 0;
for (auto gg : ed) tmp += min({d[gg.fi][gg.se], d[gg.fi][g.fi] + d[g.se][gg.se], d[gg.fi][g.se] + d[g.fi][gg.se]});
umin(ans, tmp);
}
cout << ans;
return 0;
}