T1: 邮票问题
我们应该尽可能地使用面值比较大的邮票,从而让选择的邮票数量尽可能少
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using std::cin;
using std::cout;
using std::vector;
int main() {
int n;
cin >> n;
vector<int> a{20, 10, 5, 1};
int ans = 0;
rep(i, 4) {
ans += n/a[i];
n %= a[i];
}
cout << ans << '\n';
return 0;
}
T2: 密码解锁
按题意模拟即可
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using std::cin;
using std::cout;
using std::vector;
using std::string;
int main() {
string password;
cin >> password;
vector<int> t(11);
t[3] = 1;
for (int i = 4; i <= 10; ++i) {
t[i] = 2*t[i-1];
}
int ans = 0;
string s;
int i = 1;
while (cin>>s) {
if (s == password) {
break;
}
else {
ans += t[i];
}
if (i == 10) {
puts("Locked");
return 0;
}
i++;
}
cout << ans << '\n';
return 0;
}
T3:模糊匹配
模糊匹配的定义:
- 长度相等
- \(S[i]\) 为
?
时,\(T[i]\) 任意,否则 \(S[i] == T[i]\)
还是模拟
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using std::cin;
using std::cout;
using std::string;
int main() {
string s;
cin >> s;
int n;
cin >> n;
int ans = 0;
while (n--) {
string t;
cin >> t;
if (t.size() != s.size()) continue;
bool match = true;
rep(i, s.size()) {
if (s[i] == '?') continue;
else if (s[i] != t[i]) {
match = false;
break;
}
}
if (match) ans++;
}
cout << ans << '\n';
return 0;
}
T4: 连续的零
可以考虑从结果出发
假如我们最后得到了连续的 \(k\) 个 \(0\),原本有 \(x\) 个 \(0\),\(k-x\) 个 \(1\)
至少改了 \(k-x\) 个地方 (从 \(1\) 变成 \(0\))
问的是 \(k-x\) 的最小值,这也就是 \(x\) 的最大值
于是我们可以在连续的 \(k\) 个数中找 \(x\) 的最大值
暴力的时间是 \(O(nk)\),显然超时
记 t[i]
表示连续的 \(k\) 个数中 \(0\) 的个数
注意到 \(t[i]\) 和 \(t[i+1]\) 其实它们只有两个地方不一样,所以可以由 \(t[i]\) 推出 \(t[i+1]\)
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
using std::cin;
using std::cout;
using std::max;
using std::string;
using std::vector;
using ll = long long;
int main() {
int n, k;
cin >> n >> k;
string s;
cin >> s;
vector<int> t(n+1);
rep(i, k) {
if (s[i] == '0') t[k]++;
}
int mx = t[k];
// t[i] -> t[i+1]
for (int i = k; i < n; ++i) {
int ni = i+1;
t[ni] = t[i];
if (s[i] == '0') t[ni]++;
if (s[i-k] == '0') t[ni]--;
mx = max(mx, t[ni]);
}
cout << k-mx << '\n';
return 0;
}
T5:平整序列
本题是差分的经典应用
构造数组 \(b\) 满足 \(b[i] = a[i] - a[i-1]\)
每次选择一个正的 \(b[i]\) --
,负的 \(b[j]\) ++
,这一定是最快的
代码实现
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using std::cin;
using std::cout;
using std::vector;
using ll = long long;
int main() {
int n;
cin >> n;
vector<int> a(n+2);
rep(i, n) cin >> a[i];
ll ans = 0;
vector<int> b(n+2);
rep(i, n+1) {
b[i] = a[i]-a[i-1];
if (b[i] > 0) ans += b[i];
}
cout << ans << '\n';
return 0;
}