T1:Penalty Kick
模拟
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
string ans;
for (int i = 1; i <= n; ++i) {
if (i%3 == 0) ans += 'x';
else ans += 'o';
}
cout << ans << '\n';
return 0;
}
T2:Farthest Point
暴力枚举
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int pow2(int x) { return x*x; }
int main() {
int n;
cin >> n;
vector<int> x(n), y(n);
rep(i, n) cin >> x[i] >> y[i];
rep(i, n) {
int dmax = -1, ans = -1;
rep(j, n) {
int d = pow2(x[i]-x[j]) + pow2(y[i]-y[j]);
if (dmax < d) {
dmax = d;
ans = j;
}
}
cout << ans+1 << '\n';
}
return 0;
}
T3:Colorful Beans
可以用 map
维护每种颜色中的美味度最小的豆子
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
unordered_map<int, int> d;
rep(i, n) {
int a, c;
cin >> a >> c;
if (d.count(c)) d[c] = min(d[c], a);
else d[c] = a;
}
int ans = 0;
for (auto p : d) ans = max(ans, p.second);
cout << ans << '\n';
return 0;
}
T4:Medicines on Grid
可以将每个体力药水向其他体力药水以及起点和终点加边,而能否加边取决于从当前体力药水所在的位置出发到达其他体力药水以及起点和终点的最短距离不应超过当前体力药水的能量,可以用bfs实现
建完图后,从起点出发再跑一遍bfs即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using P = pair<int, int>;
struct Med {
int r, c, e;
Med() {}
Med(int r, int c, int e): r(r), c(c), e(e) {}
};
const int INF = 1001001001;
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};
int main() {
int h, w;
cin >> h >> w;
vector<string> s(h);
rep(i, h) cin >> s[i];
int si = 0, sj = 0, ti = 0, tj = 0;
rep(i, h)rep(j, w) {
if (s[i][j] == 'S') si = i, sj = j;
if (s[i][j] == 'T') ti = i, tj = j;
}
int n;
cin >> n;
vector<Med> meds;
rep(i, n) {
int r, c, e;
cin >> r >> c >> e;
--r; --c;
meds.emplace_back(r, c, e);
}
meds.emplace_back(si, sj, 0);
meds.emplace_back(ti, tj, 0);
n += 2;
int smi = n-2, tmi = n-1;
vector<vector<int>> to(n);
rep(sv, n) {
auto [sr, sc, se] = meds[sv];
vector dist(h, vector<int>(w, INF));
queue<P> q;
dist[sr][sc] = 0; q.emplace(sr, sc);
while (q.size()) {
auto [i, j] = q.front(); q.pop();
rep(v, 4) {
int ni = i+di[v], nj = j+dj[v];
if (ni < 0 or nj < 0 or ni >= h or nj >= w) continue;
if (s[ni][nj] == '#') continue;
if (dist[ni][nj] != INF) continue;
dist[ni][nj] = dist[i][j]+1;
q.emplace(ni, nj);
}
}
rep(v, n) if (v != sv) {
auto [r, c, e] = meds[v];
if (dist[r][c] <= se) to[sv].push_back(v);
}
}
vector<int> dist(n, INF);
queue<int> q;
dist[smi] = 0; q.push(smi);
while (q.size()) {
int v = q.front(); q.pop();
for (int u : to[v]) {
if (dist[u] != INF) continue;
dist[u] = dist[v]+1;
q.push(u);
}
}
if (dist[tmi] != INF) puts("Yes");
else puts("No");
return 0;
}
T5:Minimize Sum of Distances
这题本质上就是找带权树的重心
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
int n;
cin >> n;
vector<vector<int>> to(n);
rep(i, n-1) {
int a, b;
cin >> a >> b;
--a; --b;
to[a].push_back(b);
to[b].push_back(a);
}
vector<int> c(n);
rep(i, n) cin >> c[i];
ll tot = 0;
rep(i, n) tot += c[i];
int x = -1;
{
auto dfs = [&](auto& f, int v, int p=-1) -> ll {
ll res = c[v];
ll mx = 0;
for (int u : to[v]) {
if (u == p) continue;
ll now = f(f, u, v);
mx = max(mx, now);
res += now;
}
mx = max(mx, tot-res);
if (mx*2 <= tot) x = v;
return res;
};
dfs(dfs, 0);
}
ll ans = 0;
auto dfs = [&](auto& f, int v, int dist=0, int p=-1) -> void {
ans += (ll)dist*c[v];
for (int u : to[v]) {
if (u == p) continue;
f(f, u, dist+1, v);
}
};
dfs(dfs, x);
cout << ans << '\n';
return 0;
}
T6:Oddly Similar
挺无聊的一道题,暴力加上火车头就可以跑的很快
正解做法是用 bitset
优化
代码实现
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target ("avx2")
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
cin.tie(nullptr) -> sync_with_stdio(false);
int n, m;
cin >> n >> m;
vector a(n, vector<int>(m));
rep(i, n)rep(j, m) cin >> a[i][j];
using BS = bitset<2000>;
vector<BS> d(n);
rep(k, m) {
map<int, vector<int>> is;
rep(i, n) is[a[i][k]].push_back(i);
BS x;
for (auto p : is) {
for (int i : p.second) x[i] = 1;
for (int i : p.second) d[i] ^= x;
for (int i : p.second) x[i] = 0;
}
}
int ans = 0;
rep(i, n)rep(j, i) ans += d[i][j];
cout << ans << '\n';
return 0;
}
T7:Max (Sum - Max)
决策单调性分治,代价函数可以用主席树来处理