T1:Capitalized?
模拟
代码实现
s = input()
if s.istitle():
print('Yes')
else:
print('No')
T2:Frequency
模拟
代码实现
#include <bits/stdc++.h>
using namespace std;
int main() {
string s;
cin >> s;
vector<int> cnt(256);
for (char c : s) cnt[c]++;
pair<int, char> ans(0, 'a');
for (char c = 'a'; c <= 'z'; ++c) {
ans = min(ans, make_pair(-cnt[c], c));
}
cout << ans.second << '\n';
return 0;
}
T3:Leftover Recipes
枚举做多少份料理 \(A\),然后算出剩下的材料最多可以做多少份料理 \(B\) 即可
代码实现
#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> q(n), a(n), b(n);
rep(i, n) cin >> q[i];
rep(i, n) cin >> a[i];
rep(i, n) cin >> b[i];
int ans = 0;
for (int x = 0;; ++x) {
vector<int> r(n);
rep(i, n) r[i] = q[i] - a[i]*x;
bool ok = true;
rep(i, n) if (r[i] < 0) ok = false;
if (!ok) break;
int y = 1001001001;
rep(i, n) {
if (b[i] == 0) continue;
y = min(y, r[i]/b[i]);
}
ans = max(ans, x+y);
}
cout << ans << '\n';
return 0;
}
T4:Island Tour
考虑“如果断开哪座桥,从 \(X_i\) 到 \(X_{i+1}\) 分别需要走的步数” ,注意到断开从 \(X_i\) 到 \(X_{i+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() {
int n, m;
cin >> n >> m;
vector<int> x(m);
rep(i, m) {
cin >> x[i];
x[i]--;
}
vector<ll> d(n+1);
auto add = [&](int l, int r, int x) {
d[l] += x;
d[r] -= x;
};
rep(i, m-1) {
int s = x[i], t = x[i+1];
if (s > t) swap(s, t);
int a = t-s, b = n-a;
add(0, s, a);
add(s, t, b);
add(t, n, a);
}
rep(i, n) d[i+1] += d[i];
d.pop_back();
ll ans = ranges::min(d);
cout << ans << '\n';
return 0;
}
T5:Chords
本质上是括号匹配问题,用栈来维护即可
代码实现
#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*2);
rep(i, n) {
int a, b;
cin >> a >> b;
--a; --b;
d[a] = i; d[b] = i;
}
stack<int> st;
for (int x : d) {
if (st.size() and st.top() == x) {
st.pop();
}
else st.push(x);
}
if (st.size() == 0) puts("No");
else puts("Yes");
return 0;
}
T6:Negative Traveling Salesman
floyd + 状压dp
记 dp[S][i]
表示已经遍历过的点集为 \(S\) 且当前在点 \(i\) 处的最小费用
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using namespace std;
inline void chmin(int& a, int b) { if (a > b) a = b; }
int main() {
int n, m;
cin >> n >> m;
const int INF = 1001001001;
vector g(n, vector<int>(n, INF));
rep(i, n) g[i][i] = 0;
rep(i, m) {
int a, b, c;
cin >> a >> b >> c;
--a; --b;
g[a][b] = min(g[a][b], c);
}
rep(k, n)rep(i, n)rep(j, n) chmin(g[i][j], g[i][k]+g[k][j]);
int n2 = 1<<n;
vector dp(n2, vector<int>(n, INF));
rep(i, n) dp[1<<i][i] = 0;
rep(s, n2)rep(i, n) if (dp[s][i] != INF) {
rep(j, n) if ((~s>>j&1) and g[i][j] != INF) {
int ns = s|1<<j;
chmin(dp[ns][j], dp[s][i]+g[i][j]);
}
}
int ans = ranges::min(dp[n2-1]);
if (ans == INF) puts("No");
else cout << ans << '\n';
return 0;
}