A题:Election 2
题意
两个人进行选举,已知部分投票情况,问最后结果是否一定
思路
由题意,如果结果定的话,那么就算没投票的全投给当前票少的,也不会改变结果
代码
#include <iostream>
using namespace std;
int main() {
int n, a, b; cin >> n >> a >> b;
if (a > b) swap(a, b);
cout << ((n - b > b) ? "No" : "Yes") << endl;
return 0;
}
B题: Vertical Writing
题意
将给定的N个字符串整体顺时针旋转90度,并且对于旋转后的字符串,从右往左看,“高度”不减,对于少的部分用*填补
思路
单调不减,维护一个遇到的最大值,如果当前的字符串大小小于这个值,那么就要加上*,大于的话进行更新。然后对于旋转操作,我们只需要改变输出即可。
代码
#include <iostream>
#include <vector>
using namespace std;
int main() {
int n; cin >> n;
vector<string> a(n);
for (int i = 0; i < n; i ++ ) cin >> a[i];
int cur = a[0].size();
for (int i = 1; i < n; i ++ ) {
a[i] += string(max(0, cur - (int)a[i].size()), '*');
cur = max(cur, (int)a[i].size());
}
for (int i = 0; i < cur; i ++ ) {
for (int j = n - 1; ~j; j -- ) {
if (a[j].size() < i + 1) cout << ' ';
else cout << a[j][i];
}
cout << endl;
}
return 0;
}
C题:Balls and Bag Query
题意
有三种操作,分别为
1.放入一个x。 2.拿出一个x。 3.输出当前不同的整数数量
思路
用map模拟即可
代码
#include <iostream>
#include <map>
using namespace std;
int main() {
int q; cin >> q;
map<int, int> p;
while (q -- ) {
int op, x; cin >> op;
if (op == 1) {
cin >> x;
p[x] += 1;
}else if (op == 2) {
cin >> x;
if (-- p[x] == 0) p.erase(x);
}else {
cout << p.size() << endl;
}
}
return 0;
}
D题:Cuboid Sum Query
题意
可以看作有n个二维数组,然后要求你求其中的和
思路
我们可以做n个二维前缀和,因为N值很小,那么只需要最后的时候用for将其中的所有前缀和加一起即可
#include <iostream>
using namespace std;
int a[110][110][110];
int main() {
int n; cin >> n;
for (int i = 1; i <= n; i ++ ) {
for (int j = 1; j <= n; j ++ ) {
for (int k = 1; k <= n; k ++ ) {
cin >> a[i][j][k];
a[i][j][k] += a[i][j - 1][k] + a[i][j][k - 1] - a[i][j - 1][k - 1];
}
}
}
int q; cin >> q;
while (q -- ) {
int x[3], y[3]; cin >> x[0] >> y[0] >> x[1] >> y[1] >> x[2] >> y[2];
int ans = 0;
for (int i = x[0]; i <= y[0]; i ++ ) {
ans += a[i][y[1]][y[2]] - a[i][x[1] - 1][y[2]] - a[i][y[1]][x[2] - 1] + a[i][x[1] - 1][x[2] - 1];
}
cout << ans << endl;
}
return 0;
}
E题:Manhattan Multifocal Ellipse
题意
求二维平面上,与其他N个点曼哈顿距离总和小于等于D的点的数量
思路
对于所有的点的曼哈顿距离,可以先求x的,再求y的,不必拘泥于一个一个点求,这是解决这道题的第一点
然后,我们看x
我们可以用前缀和来求对于x坐标上曼哈顿距离总和在0~D的点的数量
然后同理,可以求y的
因为是小于等于D,我们在求完x的时候,可以对dist数组做一个求前缀和的操作,
那么在y操作的时候,可以直接在答案上加上d-len即可
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
using LL = long long;
int main() {
int n, d; cin >> n >> d;
vector<int> x(n + 1), y(n + 1);
for (int i = 1; i <= n; i ++ ) cin >> x[i] >> y[i];
sort(x.begin() + 1, x.end()), sort(y.begin() + 1, y.end());
vector<LL> pre(n + 1);
vector<LL> dist(d + 1);
for (int i = 1; i <= n; i ++ ) pre[i] = pre[i - 1] + x[i];
for (int i = x[1] - d, j = 1; i <= x[n] + d; i ++ ) {
while (j <= n && i == x[j]) j += 1;
LL len = (pre[n] - pre[j - 1] - (LL)(n - j + 1) * i) + ((LL)(j - 1) * i - pre[j - 1]);
if (len <= d) dist[len] += 1;
}
for (int i = 1; i <= d; i ++ ) dist[i] += dist[i - 1];
for (int i = 1; i <= n; i ++ ) pre[i] = pre[i - 1] + y[i];
LL ans = 0;
for (int i = y[1] - d, j = 1; i <= y[n] + d; i ++ ) {
while (j <= n && i == y[j]) j += 1;
LL len = (pre[n] - pre[j - 1] - (LL)(n - j + 1) * i) + ((LL)(j - 1) * i - pre[j - 1]);
if (len <= d) ans += dist[d - len];
}
cout << ans << endl;
return 0;
}