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;
}