T1:Overall Winner
模拟
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
string s;
cin >> n >> s;
int t = 0, a = 0;
rep(i, n) {
if (s[i] == 'T') t++;
else a++;
}
if (t != a) {
if (t > a) puts("T");
else puts("A");
}
else { // t == a
if (s.back() == 'A') puts("T");
else puts("A");
}
return 0;
}
T2:Fill the Gaps
模拟
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
int main() {
int n;
cin >> n;
vector<int> a(n);
rep(i, n) cin >> a[i];
vector<int> ans;
ans.push_back(a[0]);
for (int i = 1; i < n; ++i) {
if (a[i-1] < a[i]) {
for (int x = a[i-1]+1; x <= a[i]; ++x) ans.push_back(x);
}
else {
for (int x = a[i-1]-1; x >= a[i]; --x) ans.push_back(x);
}
}
rep(i, ans.size()) cout << ans[i] << ' ';
return 0;
}
T3:AtCoder Cards
只需要检查数量的变化,而不是实际替换 ‘@’
先统计每种字符的数量,比如如果 'a' 的个数不同,就将 '@' 替换成 'a' 以减少不足的数量,然后如果最后每个字符的数量都相同的话就 OK!

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
vector<int> count(string s) {
vector<int> res(27);
for (char c : s) {
if (c == '@') res[26]++;
else res[c-'a']++;
}
return res;
}
bool solve() {
string s, t;
cin >> s >> t;
vector<int> cs = count(s);
vector<int> ct = count(t);
string A = "atcoder";
vector<bool> inA(26);
for (char c : A) inA[c-'a'] = true;
rep(i, 26) if (!inA[i]) {
if (cs[i] != ct[i]) return false;
}
rep(i, 26) if (inA[i]) {
if (cs[i] < ct[i]) {
cs[26] -= ct[i]-cs[i];
}
else {
ct[26] -= cs[i]-ct[i];
}
}
if (cs[26] < 0 or ct[26] < 0) return false;
return true;
}
int main() {
if (solve()) puts("Yes");
else puts("No");
return 0;
}
T4:Bitmask
可以考虑从高位到低位进行贪心!
如果将最高位的 ? 设置为 1,并将其他更低位的 ? 设置为 0,可以使得当前数的十进制表示数 \(\leqslant N\) 的话,则可以将最高位的 ? 设置为 1。

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
int main() {
string s;
ll n;
cin >> s >> n;
auto ten = [&](string s) {
return stoll(s, 0, 2);
};
auto f = [&](string s) {
rep(i, s.size()) {
if (s[i] == '?') s[i] = '0';
}
return ten(s) <= n;
};
if (!f(s)) {
puts("-1");
return 0;
}
rep(i, s.size()) {
if (s[i] == '?') {
s[i] = '1';
if (!f(s)) s[i] = '0';
}
}
cout << ten(s) << '\n';
return 0;
}
T5:Pac-Takahashi
可以考虑状压dp
如果先预处理出 \(S\) 和 o、\(G\) 与 o,以及任意两个 o 之间的最短路,就能像旅行商问题那样解决!
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
using P = pair<int, int>;
const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};
inline void chmin(int& a, int b) { if (a > b) a = b; }
int main() {
int h, w, T;
cin >> h >> w >> T;
vector<string> A(h);
rep(i, h) cin >> A[i];
vector<P> ps;
rep(i, h)rep(j, w) if (A[i][j] == 'o') ps.emplace_back(i, j);
rep(i, h)rep(j, w) if (A[i][j] == 'S') ps.emplace_back(i, j);
rep(i, h)rep(j, w) if (A[i][j] == 'G') ps.emplace_back(i, j);
int n = ps.size()-2;
const int INF = 1001001001;
vector dist(n+2, vector<int>(n+2, INF));
rep(si, n+2) {
auto [i, j] = ps[si];
vector d(h, vector<int>(w, INF));
queue<P> q;
d[i][j] = 0; q.emplace(i, j);
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 (A[ni][nj] == '#') continue;
if (d[ni][nj] == INF) {
d[ni][nj] = d[i][j]+1;
q.emplace(ni, nj);
}
}
}
rep(ti, n+2) {
auto [i, j] = ps[ti];
dist[si][ti] = d[i][j];
}
}
int sv = n, tv = n+1;
int n2 = 1<<n;
vector dp(n2, vector<int>(n, INF));
rep(i, n) {
dp[1<<i][i] = dist[sv][i];
}
rep(s, n2)rep(v, n) {
if (dp[s][v] == INF) continue;
rep(u, n) if (~s>>u&1) {
chmin(dp[s|1<<u][u], dp[s][v]+dist[v][u]);
}
}
if (dist[sv][tv] > T) {
puts("-1");
return 0;
}
int ans = 0;
rep(s, n2)rep(v, n) {
if (dp[s][v]+dist[v][tv] <= T) {
ans = max(ans, __builtin_popcount(s));
}
}
cout << ans << '\n';
return 0;
}
T6:Anti-DDoS
答案只需讨论以下三种情况的贡献:
- 右边仅含有小写字母
- 右边先都出现大写字母之后都是小写字母
- 左边没有重复的大写字母
第一种是针对 DDoS 的第四个字母只有小写字母
第二种是针对 DDoS 的后两个字母的出现顺序不同
第三种是针对 DDoS 的前两个字母不存在重复的大写字母
代码实现
#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;
mint perm(int n, int k) {
mint res = 1;
rep(i, k) res *= n-i;
return res;
}
int main() {
string s;
cin >> s;
int n = s.size();
vector<mint> L(n), R(n);
{
int x = 0;
vector<bool> used(26);
vector<mint> dp(27);
dp[0] = 1;
rep(i, n) {
rep(y, 27) {
L[i] += dp[y]*perm(26-x, y);
}
if (isupper(s[i])) {
if (used[s[i]-'A']) break;
used[s[i]-'A'] = true;
x++;
}
if (s[i] == '?') {
for (int y = 26; y >= 0; --y) {
if (y < 26) dp[y+1] += dp[y];
dp[y] *= 26;
}
}
}
}
mint ans;
{
mint x = 1, y = 0;
for (int i = n-1; i >= 0; --i) {
R[i] = y;
if (s[i] == '?') {
y += x;
x *= 26; y *= 26;
}
else if (isupper(s[i])) {
y += x;
x = 0;
}
else {
y = 0;
}
}
ans += x+y;
}
rep(i, n) {
mint c;
if (s[i] == '?') c = 26;
if (islower(s[i])) c = 1;
ans += L[i]*R[i]*c;
}
cout << ans.val() << '\n';
return 0;
}
浙公网安备 33010602011771号