A题: Penalty Kick
签到题
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n; cin >> n;
for (int i = 1; i <= n; i ++ ) {
if (i % 3 == 0) cout << 'x';
else cout << 'o';
}
return 0;
}
B题: Farthest Point
暴力模拟题
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n; cin >> n;
vector<int> a(n), b(n);
for (int i = 0; i < n; i ++ ) cin >> a[i] >> b[i];
for (int i = 0; i < n; i ++ ) {
int id = 0, dist = 0;
for (int j = 0; j < n; j ++ ) {
if (i == j) continue;
int now = (a[j] - a[i]) * (a[j] - a[i]) + (b[j] - b[i]) * (b[j] - b[i]);
if (now > dist) {
id = j;
dist = now;
}
}
cout << id + 1 << endl;
}
return 0;
}
C题: Colorful Beans
思路:用桶(map)存对应颜色的最小美味度,然后遍历取最大即可。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n; cin >> n;
map<int, int> p;
for (int i = 0; i < n; i ++ ) {
int a, c;
cin >> a >> c;
if (!p[c]) p[c] = a;
else p[c] = min(p[c], a);
}
int ans = 0;
for (auto t : p) {
ans = max(ans, t.second);
}
cout << ans << endl;
return 0;
}
D题: Medicines on Grid
显然bfs,不过vis数组要改一下,不能简单地使用bool数组,可以参考最后一个样例。
vis存的是到当前点的最大能量,这样我们bfs的时候,只有当能量大于vis的时候才丢到queue里面。
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
const int N = 210;
char g[N][N];
int vis[N][N], b[N][N];
int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
memset(vis, -1, sizeof vis);
int h, w;
cin >> h >> w;
pair<int, int> f;
queue<array<int, 3>> q;
for (int i = 1; i <= h; i ++ ) {
for (int j = 1; j <= w; j ++ ) {
cin >> g[i][j];
if (g[i][j] == 'S') {
q.push({i, j, 0});
}
if (g[i][j] == 'T') {
f = {i, j};
}
}
}
int n; cin >> n;
while (n -- ) {
int r, c, e; cin >> r >> c >> e;
b[r][c] = e;
}
while (q.size()) {
auto t = q.front(); q.pop();
int x = t[0], y = t[1], e = t[2];
e = max(b[x][y], e);
vis[x][y] = e;
if (e <= 0) continue;
for (int i = 0; i < 4; i ++ ) {
int x1 = x + dx[i], y1 = y + dy[i];
if (x1 < 1 || x1 > h || y1 < 1 || y1 > w) continue;
if (vis[x1][y1] >= e - 1) continue;
if (g[x1][y1] == '#') continue;
q.push({x1, y1, e - 1});
vis[x1][y1] = e - 1;
}
}
if (vis[f.first][f.second] < 0) cout << "No\n";
else cout << "Yes\n";
return 0;
}
E题: Minimize Sum of Distances
换根dp
推荐up主->
【Atcoder ABC348 E讲解(换根DP)】https://www.bilibili.com/video/BV14m42177cJ?vd_source=140a9a07403bc18393f243c29b890edf
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
const int N = 1e5 + 9;
int n; ll tot;
ll a[N], dp[N], sum[N];
vector<int> e[N];
void dfs(int now, int lst, ll dep) {
dp[1] += a[now] * dep;
sum[now] += a[now];
for (auto x : e[now]) {
if (x == lst) continue;
dfs(x, now, dep + 1);
sum[now] += sum[x];
}
tot += a[now];
}
void ddfs(int now, int lst) {
for (auto x : e[now]) {
if (x == lst) continue;
dp[x] = dp[now] + tot - 2 * sum[x];
ddfs(x, now);
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n;
for (int i = 1; i < n; i ++ ) {
int u, v; cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
for (int i = 1; i <= n; i ++ ) cin >> a[i];
dfs(1, 0, 0);
ll ans = dp[1];
ddfs(1, 0);
for (int i = 2; i <= n; i ++ ) ans = min(ans, dp[i]);
cout << ans << endl;
return 0;
}
F题: Oddly Similar
显然暴力的方法是O(),这肯定是过不了的。
所以我们可以结合位运算的知识,进行解题。
我们用bs存每列中元素存在的位置,用bt存每行的信息
我们只是在找固定一列后,每行相等的元素进行操作!
从矩阵左边往右边看,一开始大家都没有相似,然后看第一列,会将与其值相等的列异或到bt里面去,接着再进行操作,如果还是之前相同的行,这样异或起来就会是0,而同值不同的行可以异或为1,这样就实现了题目的模拟。
如果列数是奇数,那么每行都存在自己跟自己的一种情况,要减去n。
然后这是相互的,所以ans / 2
#include <bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n, m; cin >> n >> m;
vector<vector<int>> a(n, vector<int>(m));
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < m; j ++ ) {
cin >> a[i][j];
}
}
vector<bitset<2000>> bt(n);
vector<bitset<2000>> bs(1000);
for (int i = 0; i < m; i ++ ) {
for (int j = 0; j < n; j ++ ) {
bs[a[j][i]].set(j);
}
for (int j = 0; j < n; j ++ ) {
bt[j] ^= bs[a[j][i]];
}
for (int j = 0; j < n; j ++ ) {
bs[a[j][i]].reset(j);
}
}
int ans = 0;
for (int i = 0; i < n; i ++ ) ans += bt[i].count();
if (m & 1) ans -= n;
cout << ans / 2 << endl;
return 0;
}