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,可以使得当前数的十进制表示数 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
如果先预处理出 SoGo,以及任意两个 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;
}