T1:Print 341

模拟

代码实现
n = int(input())
print('1'+'01'*n)

T2:Foreign Exchange

模拟

代码实现
n = int(input())
a = list(map(int, input().split()))
for i in range(n-1):
    s, t = map(int, input().split())
    x = a[i]//s 
    a[i+1] += t*x
print(a[-1])

T3:Takahashi Gets Lost

暴搜

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

using namespace std;

int main() {
    int h, w, n;
    cin >> h >> w >> n;
    
    string t;
    cin >> t;
    
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    
    int ans = 0;
    rep(si, h)rep(sj, w) {
        if (s[si][sj] == '#') continue;
        bool ok = true;
        int i = si, j = sj;
        for (char c : t) {
            if (c == 'L') j--;
            if (c == 'R') j++;
            if (c == 'U') i--;
            if (c == 'D') i++;
            if (s[i][j] == '#') {
                ok = false;
                break;
            }
        }
        if (ok) ans++;
    }
    
    cout << ans << '\n';
    
    return 0;
}

T4:Only one of two

考虑二分答案

\(f(x)\) 表示在 \(1 \sim x\) 中满足条件的数的个数

那么 \(f(x) = \lfloor\frac{x}{n}\rfloor + \lfloor\frac{x}{m}\rfloor - 2 \times \frac{x}{\operatorname{lcm}(n, m)}\)

判定条件为 \(f(x) \geqslant k\)

代码实现
#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, m, k;
    cin >> n >> m >> k;
    ll l = lcm(n, m);
    
    auto f = [&](ll x) {
        ll c = x/n + x/m - x/l*2;
        return c >= k;
    };
    
    ll wa = 0, ac = 1e18;
    while (ac-wa > 1) {
        ll wj = (ac+wa)/2;
        if (f(wj)) ac = wj; else wa = wj;
    }
    
    cout << ac << '\n';
    
    return 0;
}

T5:Alternating String

注意到操作 \(1\) 并不会更改区间 \([l, r],[1, l-1], [r+1, n]\) 中的相邻元素之间的关系,而只会影响 \(s_{l-1}\)\(s_l\) 以及 \(s_r\)\(s_{r+1}\) 的关系

可以用 std::set 来维护两个相同字符的关系,即若 \(s_i = s_{i+1}\),则将 \(i+1\) 加入 set 中,对于操作 \(2\),只需在 set 中查找是否存在大于等于 \(l+1\) 的某个元素不超过 \(r\) 即可

代码实现
#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;
    string s;
    cin >> s;
    
    set<int> st;
    rep(i, n-1) {
        if (s[i] == s[i+1]) st.insert(i+1);
    }
    st.insert(n+1);
    
    rep(qi, q) {
        int type, l, r;
        cin >> type >> l >> r;
        --l;
        if (type == 1) {
            if (st.count(l)) st.erase(l); else st.insert(l);
            if (st.count(r)) st.erase(r); else st.insert(r);
        }
        else {
            int i = *st.lower_bound(l+1);
            if (i < r) puts("No");
            else puts("Yes");
        }
    }
    
    return 0;
}

T6:Breakdown

先将所有点按 \(W_i\) 的大小做升序排序,然后跑一遍01背包即可

dp[v] 表示点 \(v\) 上有 \(1\) 个棋子时从这个点开始执行操作的最大次数
dp2[j] 表示 \(\sum W_i = j\) 时的 \(\sum dp[u]\) 的最大值

代码实现
#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, m;
    cin >> n >> m;
    
    vector<vector<int>> to(n);
    rep(i, m) {
        int a, b;
        cin >> a >> b;
        --a; --b;
        to[a].push_back(b);
        to[b].push_back(a);
    }
    
    vector<int> w(n), a(n);
    rep(i, n) cin >> w[i];
    rep(i, n) cin >> a[i];
    
    vector<int> vs(n);
    rep(i, n) vs[i] = i;
    sort(vs.begin(), vs.end(), [&](int i, int j) { return w[i] < w[j]; });
    
    vector<int> dp(n);
    for (int v : vs) {
        vector<int> dp2(w[v]);
        for (int u : to[v]) {
            if (w[u] >= w[v]) continue;
            for (int j = w[v]-1; j >= w[u]; --j) {
                dp2[j] = max(dp2[j], dp2[j-w[u]]+dp[u]);
            }
        }
        dp[v] = dp2[w[v]-1]+1;
    }
    
    ll ans = 0;
    rep(i, n) ans += (ll)a[i]*dp[i];
    
    cout << ans << '\n';
    
    return 0;
}

T7:Highest Ratio

\(S_i = A_1 + A_2 + \cdots + A_i\)
倒序维护点 \((i, S_i)\) 构成的上凸包即可
时间复杂度为 \(\mathcal{O}(n)\)

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

using namespace std;
using ll = long long;

struct P {
    ll x, y;
    P(ll x=0, ll y=0): x(x), y(y) {}
};

int main() {
    int n;
    cin >> n;
    
    vector<int> a(n);
    rep(i, n) cin >> a[i];
    vector<ll> s(n+1);
    rep(i, n) s[i+1] = s[i]+a[i];
    
    vector<double> ans(n);
    vector<P> ps;
    ps.emplace_back(n, s[n]);
    for (int i = n-1; i >= 0; --i) {
        P p(i, s[i]);
        while (ps.size() >= 2) {
            P a = ps[ps.size()-1];
            P b = ps[ps.size()-2];
            a.x -= p.x; a.y -= p.y;
            b.x -= p.x; b.y -= p.y;
            if (a.y*b.x > b.y*a.x) break;
            ps.pop_back();
        }
        P a = ps.back();
        a.x -= p.x; a.y -= p.y;
        ans[i] = 1.*a.y/a.x;
        ps.emplace_back(p);
    }
    
    rep(i, n) printf("%.10f\n", ans[i]);
    
    return 0;
}