T1:Takahashi san

模拟

代码实现
#include <bits/stdc++.h>

using namespace std;

int main() {
    string s, t;
    cin >> s >> t;
    
    cout << s << ' ' << "san";
    
    return 0;

}

T2:World Meeting

暴力枚举

代码实现
#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> w(n), x(n);
    rep(i, n) cin >> w[i] >> x[i];
    
    int ans = 0;
    rep(t, 24) {
        int now = 0;
        rep(i, n) {
            int y = (x[i]+t)%24;
            if (9 <= y and y < 18) now += w[i];
        }
        ans = max(ans, now);
    }
    
    cout << ans << '\n';
    
    return 0;

}

T3:Sensors

经典题 Lake Counting

代码实现
#include <bits/stdc++.h>
#if __has_include(<atcoder/all>)
#include <atcoder/all>
using namespace atcoder;
#endif
#define rep(i, n) for (int i = 0; i < (n); ++i)

using namespace std;

int main() {
    int h, w;
    cin >> h >> w;
    
    vector<string> s(h);
    rep(i, h) cin >> s[i];
    
    int ans = 0;
    int n = h*w;
    dsu uf(n);
    rep(i, h)rep(j, w) {
        if (s[i][j] != '#') continue;
        ans++;
        for (int di = -1; di <= 1; ++di) {
            for (int dj = -1; dj <= 1; ++dj) {
                int ni = i+di, nj = j+dj;
                if (ni < 0 or ni >= h or nj < 0 or nj >= w) continue;
                if (s[ni][nj] != '#') continue;
                if (i == ni and j == nj) continue;
                int v = i*w+j, u = ni*w+nj;
                if (uf.same(v, u)) continue;
                uf.merge(v, u);
                ans--;
            }
        }
    }
    
    cout << ans << '\n';
    
    return 0;

}

T4:Printing Machine

在当前可以打印的商品中优先打印截止时间最早的那个
用小根堆维护一下右端点即可

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

using namespace std;
using ll = long long;
using P = pair<ll, ll>;

int main() {
    int n;
    cin >> n;
    
    vector<P> a;
    rep(i, n) {
        ll t, d;
        cin >> t >> d;
        a.emplace_back(t, t+d);
    }
    
    sort(a.begin(), a.end());
    
    int ans = 0;
    ll t = 0;
    int ai = 0;
    priority_queue<ll, vector<ll>, greater<ll>> q;
    while (ai < n or q.size()) {
        while (ai < n and a[ai].first <= t) {
            q.push(a[ai].second);
            ai++;
        }
        while (q.size() and q.top() < t) q.pop();
        if (q.size()) ans++, q.pop();
        if (!q.size() and ai < n) t = a[ai].first;
        else t++;
    }
    
    cout << ans << '\n';
    
    return 0;

}

T5:Our clients, please wait a moment

跑朴素版的Dijkstra即可
时间复杂度为 \(\mathcal{O}(N^2)\)

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

using namespace std;
using ll = long long;
using P = pair<ll, int>;

int main() {
    int n; ll a, b, c;
    cin >> n >> a >> b >> c;
    
    vector d(n, vector<int>(n));
    rep(i, n)rep(j, n) cin >> d[i][j];
    
    const ll INF = 1e18;
    auto dijk = [&](int sv, ll b, ll c) {
        vector<ll> dist(n, INF);
        vector<bool> done(n);
        dist[sv] = 0;
        rep(ni, n) {
            P best(INF, 0);
            rep(i, n) if (!done[i]) best = min(best, P(dist[i], i));
            int v = best.second;
            done[v] = true;
            rep(i, n) {
                dist[i] = min(dist[i], dist[v]+d[v][i]*b+c);
            }
        }
        return dist;
    };
    
    auto d1 = dijk(0, a, 0);
    auto d2 = dijk(n-1, b, c);
    
    ll ans = INF;
    rep(i, n) ans = min(ans, d1[i]+d2[i]);
    
    cout << ans << '\n';
    
    return 0;

}

T6:Sensor Optimization Dilemma

dp[i][x] 表示到第 \(i\) 个区间为止,在使用 \(x\) 个类型 \(1\) 的传感器的前提下需要使用类型 \(2\) 的传感器的最少数量

时间复杂度为 \(\mathcal{O}(NK_1^2)\)

代码实现
#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;
	cin >> n;
	
	vector<int> d(n);
	rep(i, n) cin >> d[i];
	
	int l1, k1; ll c1; 
	int l2, k2; ll c2; 
	cin >> l1 >> c1 >> k1;
	cin >> l2 >> c2 >> k2;
	
	const int INF = 1001001001;
	vector<int> dp(k1+1, INF);
	dp[0] = 0;
	rep(i, n) {
	    vector<int> p(k1+1, INF);
	    swap(dp, p);
	    rep(x1, k1+1) {
	        int x2 = ((d[i]-l1*x1)+l2-1)/l2;
	        x2 = max(x2, 0);
	        rep(j, k1+1-x1) {
	            dp[j+x1] = min(dp[j+x1], p[j]+x2);
	        }
	    }
	}
	
	ll ans = 1e18;
	rep(i, k1+1) {
	    int j = dp[i];
	    if (j > k2) continue;
	    ll now = i*c1 + j*c2;
	    ans = min(ans, now);
	}
	
	if (ans == 1e18) ans = -1;
	cout << ans << '\n';
	
	return 0;
}

T7:offence

区间dp
dp[l][r] 表示对区间 \([l, r)\) 操作所能剩下的最少的字符数

代码实现
#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(int& a, int b) { if (a > b) a = b; }

int main() {
	string s; int k;
	cin >> s >> k;
	int n = s.size();
	
	const int INF = 1001001001;
	vector dp(n+1, vector<int>(n+1, INF));
	for (int w = 0; w <= n; ++w) {
	    for (int l = 0; l <= n; ++l) {
	        int r = l+w;
	        if (r > n) break;
	        dp[l][r] = r-l;
	        for (int i = l+1; i < r; ++i) {
	            chmin(dp[l][r], dp[l][i]+dp[i][r]);
	            if (s[l] == 'o' and s[i] == 'f') {
	                if (dp[l+1][i] == 0 and dp[i+1][r] <= k) {
	                    dp[l][r] = 0;
	                }
	            }
	        }
	    }
	}
	
	cout << dp[0][n] << '\n';
	
	return 0;
}