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) 表示在 1x 中满足条件的数的个数

那么 f(x)=xn+xm2×xlcm(n,m)

判定条件为 f(x)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,l1],[r+1,n] 中的相邻元素之间的关系,而只会影响 sl1sl 以及 srsr+1 的关系

可以用 std::set 来维护两个相同字符的关系,即若 si=si+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

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

dp[v] 表示点 v 上有 1 个棋子时从这个点开始执行操作的最大次数
dp2[j] 表示 Wi=j 时的 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

Si=A1+A2++Ai
倒序维护点 (i,Si) 构成的上凸包即可
时间复杂度为 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;
}