A. Lucky Direction
模拟
代码实现
d = {'N' : 'S', 'S' : 'N', 'W' : 'E', 'E' : 'W'}
print(''.join(d[c] for c in input()))
B. Seek Grid
暴搜
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, m;
cin >> n >> m;
vector<string> s(n), t(m);
rep(i, n) cin >> s[i];
rep(i, m) cin >> t[i];
rep(a, n-m+1)rep(b, n-m+1) {
bool ok = true;
rep(i, m)rep(j, m) {
if (s[a+i][b+j] != t[i][j]) {
ok = false;
break;
}
}
if (ok) {
cout << a+1 << ' ' << b+1 << '\n';
return 0;
}
}
return 0;
}
C. Pigeonhole Query
维护每只鸽子在哪个巢里,同时维护每个巢里的鸽子数,对于超过 \(1\) 只鸽子的巢只需考察每个巢里的鸽子数的变化量
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, q;
cin >> n >> q;
vector<int> hole(n);
rep(i, n) hole[i] = i;
vector<int> cnt(n, 1);
int ans = 0;
auto addCnt = [&](int h, int x) {
if (cnt[h] >= 2) ans--;
cnt[h] += x;
if (cnt[h] >= 2) ans++;
};
rep(qi, q) {
int type;
cin >> type;
if (type == 1) {
int p, h;
cin >> p >> h;
--p; --h;
addCnt(hole[p], -1);
hole[p] = h;
addCnt(hole[p], 1);
}
else {
cout << ans << '\n';
}
}
return 0;
}
D. Gravity
经过 \(T\) 时刻后,每个方块位于 \(\max(1, Y_i-T)\) 的位置
维护每个方块所在列的下方有多少个方块,记为 \(r_i\)
令 \(d_j\) 表示每列满足 \(r_i = j\) 的方块的消失时间
然后模拟一下即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n, w;
cin >> n >> w;
vector<int> x(n), y(n);
rep(i, n) {
cin >> x[i] >> y[i];
x[i]--;
}
vector<int> ord(n);
rep(i, n) ord[i] = i;
ranges::sort(ord, [&](int i, int j) { return y[i] < y[j]; });
vector<int> r(n);
vector<int> num(w);
for (int i : ord) {
r[i] = num[x[i]];
num[x[i]]++;
}
const int INF = 1001001001;
vector<int> d(n, INF);
{
vector<vector<int>> blocks(n);
rep(i, n) blocks[r[i]].push_back(i);
rep(i, n) {
if (blocks[i].size() != w) continue;
int mx = 0;
for (int j : blocks[i]) mx = max(mx, y[j]-1);
d[i] = mx+1;
}
}
int q;
cin >> q;
rep(qi, q) {
int t, a;
cin >> t >> a;
--a;
if (d[r[a]] > t) puts("Yes");
else puts("No");
}
return 0;
}
E. Hierarchical Majority Vote
三分树
记 dp[v][i] 表示将点 \(v\) 的点权变为 \(i\) 时的费用(以点 \(v\) 为根的子树中的所有点的点权全部确定)
跑树形dp
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
inline void chmin(int& x, int y) { if (x > y) x = y; }
int main() {
int n;
string s;
cin >> n >> s;
vector dp(s.size(), vector<int>(2, 1));
rep(i, s.size()) dp[i][s[i]-'0'] = 0;
const int INF = 1001001001;
while (dp.size() > 1) {
vector old(dp.size()/3, vector<int>(2, INF));
swap(dp, old);
for (int l = 0; l < old.size(); l += 3) {
rep(s, 8) {
int cost = 0;
rep(i, 3) cost += old[l+i][s>>i&1];
int x = __builtin_popcount(s) >= 2 ? 1 : 0;
chmin(dp[l/3][x], cost);
}
}
}
int ans = max(dp[0][0], dp[0][1]);
cout << ans << '\n';
return 0;
}
F. K-th Largest Triplet
先分别对这三个序列做降序排序
然后做多路归并即可
代码实现
#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, K;
cin >> n >> K;
vector<ll> a(n), b(n), c(n);
rep(i, n) cin >> a[i];
rep(i, n) cin >> b[i];
rep(i, n) cin >> c[i];
ranges::sort(a, greater<>());
ranges::sort(b, greater<>());
ranges::sort(c, greater<>());
priority_queue<tuple<ll, int, int, int>> q;
auto push = [&](int i, int j, int k) {
if (i >= n or j >= n or k >= n) return;
ll val = a[i]*b[j] + b[j]*c[k] + c[k]*a[i];
q.emplace(val, i, j, k);
};
push(0, 0, 0);
rep(ki, K-1) {
auto [val, i, j, k] = q.top(); q.pop();
push(i+1, j, k);
if (i == 0) push(i, j+1, k);
if (i == 0 and j == 0) push(i, j, k+1);
}
ll ans = get<0>(q.top());
cout << ans << '\n';
return 0;
}
G. Many LCS
dp套dp的板题
回忆 \(S\) 和 \(T\) 的LCS
记 dp[i][j] 表示 \(S[0:i]\) 和 \(T[0:j]\) 的LCS
再来考虑原题:
记 DP[i][d] 表示使 \(T[0:i]\) 和 \(S\) 的LCS的 dp 表为 \(d\) 的 \(T\) 串数
具体可以参考 类似题的题解
代码实现
#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;
inline void chmax(int& x, int y) { if (x < y) x = y; }
int main() {
int n, m;
string s;
cin >> n >> m >> s;
using vi = vector<int>;
map<vi, mint> dp;
dp[vi(n+1)] = 1;
rep(mi, m) {
map<vi, mint> old;
swap(dp, old);
for (auto [d, x] : old) {
rep(c, 26) {
vi nd = d;
rep(i, n) if (c == s[i]-'a') {
chmax(nd[i+1], d[i]+1);
}
rep(i, n) chmax(nd[i+1], nd[i]);
dp[nd] += x;
}
}
}
vector<mint> ans(n+1);
for (auto [d, x] : dp) ans[d[n]] += x;
rep(i, n+1) cout << ans[i].val() << ' ';
return 0;
}
浙公网安备 33010602011771号