小白月赛94
A 小苯的九宫格
现在小苯有一个可能乱序的九宫格按键,但他没注意到九宫格是乱序,因此他还是按照正常九宫格顺序点击的按键。
(正常九宫格:也就是按照 1 到 9分为三行三列,从上到下,从左到右都是递增的)
请你告诉他,在他点击完按键后,屏幕上显示的数字都应该是什么?
void solve() {
int a[4][4] = {};
for (int i = 0;i < 3;i++) {
for (int j = 0;j < 3;j++) {
cin >> a[i][j];
}
}
string s;cin >> s;
for (int i = 0;i < s.size();i++) {
cout << a[(s[i] - '0' - 1) / 3][(s[i] - '0' + 2) % 3];
}
}
B 小苯的好数组
如果一个数组按升序排序后和原来不完全相同,则其是一个好数组。
小苯想知道,如果想要使得选择的子序列构成一个“好数组”,最长可以选多长的子序列?
void solve() {
int n;cin >> n;
vector<int> a(n + 1);
for (int i = 1;i <= n;i++)cin >> a[i];
for (int i = 2;i <= n;i++) {
if (a[i] < a[i - 1]) {
cout << n << "\n";return;
}
}
cout << 0 << '\n';
}
C 小苯的数字合并
给定一个数组
可以执行操作任意次:将两个数字合并。
很明显的前缀和
#define int long long
void solve() {
int n;cin >> n;
vector<int> a(n + 1), pre(n + 1);
for (int i = 1;i <= n;i++)cin >> a[i];
for (int i = 1;i <= n;i++)pre[i] = pre[i - 1] + a[i];
int ans = 0;
for (int i = 1;i <= n;i++) {
int x = pre[i - 1] - pre[0] - a[i];
int y = pre[n] - pre[i] - a[i];
ans = max({ans,x,y});
}
cout << ans << '\n';
}
D 小苯的排列构造
给定一个数组
非常致命的坑点:
last
,若不用一个变量来保存的话,若前后两个相等(这种情况是最多的),会导致每个 都会重复计算一遍,会导致超时。如:在这份代码若将 last 拿出 if 条件将会超时。
void solve() {
int n;cin >> n;
vector<int> a(n + 1), ans(n + 1), vis(n + 1);
for (int i = 1;i <= n;i++)cin >> a[i];
int last = 0;
for (int i = 1;i <= n;i++) {
if (a[i] != a[i - 1]) {
if (a[i - 1] % a[i] != 0) {
cout << -1 << "\n";return;
}
last = a[i];
}
while (last <= n && vis[last])last += a[i];
if (last > n) {
cout << "-1\n";return;
} else {
ans[i] = last, vis[last] = 1;
}
}
for (int i = 1;i <= n;i++)
cout << ans[i] << " \n"[i == n];
}
E/F 小苯的 01 背包
一个背包的容量为
在体积不超过
本题物品的总体积与总价值都定义为所装物品的按位与
easy
:hard
:
easy:
这个版本的思路就是枚举答案:
由于体积和价值都是
void solve() {
int n, k;cin >> n >> k;
vector<pair<int, int>> p(n);
for (auto& [v, w] : p) cin >> v >> w;
int ans = 0;
for (int i = 0; i <= 2000; i ++) {
vector<pair<int, int>> s;
for (auto [v, w] : p)
if ((w & i) == i) s.emplace_back(v, w);
if (s.empty()) continue;
auto [sv, sw] = s[0];
for (auto [v, w] : s) {
sv &= v,sw &= w;
}
if (sv <= k) ans = max(ans, sw);
}
cout << ans;
}
hard:
和简单版本相比只是从枚举答案到枚举每一位,从高到低位贪心的看相应那一位是否满足。得到的一定是最大的。
void solve() {
int n, k;cin >> n >> k;
vector<pair<int, int>> p(n);
for (auto& [v, w] : p) cin >> v >> w;
int i = 0;
for (int j = 30; j >= 0; j --) {
vector<pair<int, int>> s;
i += 1 << j;
for (auto [v, w] : p)
if ((w & i) == i) s.emplace_back(v, w);
if (s.empty()) {
i -= 1 << j;
continue;
}
auto [sv, sw] = s[0];
for (auto [v, w] : s) {
sv &= v;
sw &= w;
}
if (sv > k) i -= 1 << j;
}
cout << i;
}