A. ABC400 Party

模拟

代码实现
a = int(input())
b, r = divmod(400, a)
print(b if r == 0 else -1)

B. Sum of Geometric Series

模拟

代码实现
n, m = map(int, input().split())
ans = sum(n**i for i in range(m+1))
if ans > 10**9:
    ans = 'inf'
print(ans)

C. 2^a b^2

\(a < 60\)\(b < 10^9\)

只需考虑 \(b\) 为奇数的情况就可以避免重复。然后,通过枚举 \(a\) 并计算 \(b\) 的候选数量即可!还需注意 sqrt 的误差

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

int main() {
    ll n;
    cin >> n;
    
    ll ans = 0;
    for (int a = 1; a < 60; ++a) {
        ll x = n;
        rep(i, a) x /= 2;
        ll m = sqrtl(x);
        ans += (m+1)/2;
    }
    
    cout << ans << '\n';
    
    return 0;
}

D. Takahashi the Wall Breaker

01bfs
这是一个最短路问题,其中普通上下左右移动的费用为 \(0\),而跨一堵或两堵墙移动的费用为 \(1\)

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

const int di[] = {-1, 0, 1, 0};
const int dj[] = {0, 1, 0, -1};

int main() {
    int h, w;
    cin >> h >> w;
    
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    
    int si, sj, ti, tj;
    cin >> si >> sj >> ti >> tj;
    --si; --sj; --ti; --tj;
    
    const int INF = 1001001001;
    vector dist(h, vector<int>(w, INF));
    vector used(h, vector<bool>(w));
    deque<pair<int, int>> q;
    
    auto push = [&](int i, int j, int d, int cost) {
        if (dist[i][j] <= d) return;
        dist[i][j] = d;
        if (cost == 0) q.emplace_front(i, j);
        else q.emplace_back(i, j);
    };
    push(si, sj, 0, 0);
    
    while (q.size()) {
        auto [i, j] = q.front(); q.pop_front();
        if (used[i][j]) continue;
        used[i][j] = true;
        int d = dist[i][j];
        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 (s[ni][nj] == '.') push(ni, nj, d, 0);
        }
        rep(v, 4) {
            int ni = i, nj = j;
            rep(k, 2) {
                ni += di[v], nj += dj[v];
                if (ni < 0 or nj < 0 or ni >= h or nj >= w) break;
                push(ni, nj, d+1, 1);
            }
        }
    }
    
    int ans = dist[ti][tj];
    cout << ans << '\n';
    
    return 0;
}

E. Ringo's Favorite Numbers 3

\(1 \sim \sqrt{A}\) 中每个数判定它是否仅包含两个素因子
为了加速,可以从后往前验证

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

int main() {
    const int M = 1e6;
    vector<int> cnt(M+1);
    for (int i = 2; i <= M; ++i) {
        if (cnt[i]) continue;
        for (int j = i; j <= M; j += i) cnt[j]++;
    }
    
    int q;
    cin >> q;
    rep(qi, q) {
        ll a;
        cin >> a;
        ll x = sqrt(a);
        while (cnt[x] != 2) x--;
        cout << x*x << '\n';
    }
    
    return 0;
}

F. Happy Birthday! 3

区间dp
dp[l][r] 表示将区间 \([l, r]\) 染成目标颜色的最小代价
dp2[l][r] 表示将区间 \([l, r]\) 染成目标颜色或 \(c[l]\) 的最小代价

代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;
using ll = long long;

inline void chmin(ll& x, ll y) { if (x > y) x = y; }

int main() {
    int n;
    cin >> n;
    
    vector<int> c(n), x(n);
    rep(i, n) cin >> c[i], c[i]--;
    rep(i, n) cin >> x[i];
    
    const ll INF = 1e18;
    vector dp(n, vector<ll>(n, INF));
    vector dp2(n, vector<ll>(n, INF));
    rep(i, n) dp2[i][i] = x[c[i]];
    
    auto get = [&](int l, int r) {
        l = (l+n)%n;
        r = (r+n)%n;
        return dp[l][r];
    };
    auto get2 = [&](int l, int r) {
        l = (l+n)%n;
        r = (r+n)%n;
        return dp2[l][r];
    };
    
    for (int w = 1; w <= n; ++w) {
        rep(l, n) {
            int r = (l+w-1)%n;
            if (w > 1 and c[l] == c[r]) chmin(dp2[l][r], get2(l, r-1));
            rep(i, w-1) chmin(dp2[l][r], get2(l, l+i)+get(l+i+1, r));
            
            chmin(dp[l][r], dp2[l][r]+w);
            rep(i, w-1) {
                chmin(dp[l][r], get(l, l+i)+get(l+i+1, r));
            }
        }
    }
    
    ll ans = INF;
    rep(l, n) chmin(ans, get(l, l+n-1));
    cout << ans << '\n';
    
    return 0;
}

G. Patisserie ABC 3

将美观度、美味度、受欢迎度打个标记,分别记为 \(1, 2, 3\)
假设蛋糕按 \(\max(X_i, Y_i, Z_i)\) 从大到小排序时,以下成立。

  • 存在一个最优解,其中从蛋糕 \(1\) 到蛋糕 \(2K\) 中,未被取到的蛋糕数量不超过 \(2\) 个。

定义 dp[i][j][k] 为“在考虑到第 \(i\) 个蛋糕时,被取到的蛋糕数量为 \(\min(2K,i)−j\),且每个标记的使用次数的奇偶性由 \(k\) 表示的情况下,价格的最大值”
由于 \(j\) 只需在 \(0\)\(2\) 之间进行搜索,因此通过状态数为 \(24N\) 的动态规划,可以解决这个问题。