AtCoder Beginner Contest 366 A-F
AtCoder Beginner Contest 366 (opens new window)
# A - Election 2
# Code
#include <bits/stdc++.h>
using namespace std;
int main() {
int N, A , B ; cin >> N >> A >> B;
int A_ = N - (A + B) + A;
if (A_ < B) {
cout << "Yes" << endl;
return 0;
}
int B_ = N - (A + B) + B;
if (B_ < A) {
cout << "Yes" << endl;
return 0;
}
cout << "No" << endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# B - Vertical Writing
# Code
#include <bits/stdc++.h>
using namespace std;
int main() {
int N; cin >> N;
vector<string> S(N);
int M = -1;
for (int i = 0; i < N; i++) {
cin >> S[i];
M = max(M, (int)S[i].size());
}
vector<vector<char>> A(N, vector<char>(M, 0));
for (int i = 0; i < N; i++) {
for (int j = 0; j < S[i].size(); j++) {
A[i][j] = S[i][j];
}
for (int j = S[i].size(); j < M; j++) {
A[i][j] = '*';
}
}
for (int j = 0; j < M; j++) {
for (int i = 0; i < N; i++) {
if (A[i][j] == '*') A[i][j] = ' ';
else break;
}
}
for (int j = 0; j < M; j++) {
for (int i = N - 1; i >= 0; i--) {
cout << A[i][j];
}
cout << endl;
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# C - Balls and Bag Query
# Solution
使用 p 数组记录一个数出现了几次,用 维护答案
# Code
#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
int main() {
int Q; cin >> Q;
vector<int> p(maxn, 0);
int cnt = 0;
while (Q--) {
int op; cin >> op;
if (op == 1) {
int x; cin >> x;
if (p[x]++ == 0) cnt += 1;
}
else if (op == 2) {
int x; cin >> x;
if (--p[x] == 0) cnt -= 1;
}
else {
cout << cnt << endl;
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# D - Cuboid Sum Query
# Solution
三维容斥
# Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
signed main() {
ios::sync_with_stdio(0);
int n; cin >> n;
vector<vector<vector<int>>> a(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 0)));
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];
}
vector<vector<vector<int>>> s(n + 1, vector<vector<int>>(n + 1, vector<int>(n + 1, 0)));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
for (int k = 1; k <= n; k++) {
s[i][j][k] = s[i - 1][j][k] + s[i][j - 1][k] + s[i][j][k - 1] - s[i - 1][j - 1][k] - s[i - 1][j][k - 1] - s[i][j - 1][k - 1] + s[i - 1][j - 1][k - 1] + a[i][j][k];
}
int Q; cin >> Q;
while (Q--) {
int x1, y1, z1, x2, y2, z2; cin >> x1 >> x2 >> y1 >> y2 >> z1 >> z2;
cout << s[x2][y2][z2] - s[x1 - 1][y2][z2] - s[x2][y1 - 1][z2] - s[x2][y2][z1 - 1] + s[x1 - 1][y1 - 1][z2] + s[x1 - 1][y2][z1 - 1] + s[x2][y1 - 1][z1 - 1] - s[x1 - 1][y1 - 1][z1 - 1] << endl;
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# E - Manhattan Multifocal Ellipse
# Question
给定 个点 在二维平面上,以及非负整数 。
找出满足 的整数对 的数量。
# Solution
先把 分开,其实可以独立的来看这个问题
设 ,那么答案就是满足 的 数对的数量
首先,我们发现值域其实不大,我们需要对序列中的每个 ,都求出其 ,我们可以用递推来计算,假设我们已知 ,并且知道比 小的 有 个,那么有 个的距离需要增加 ,有 个的距离需要减少 ,所以,
同理,我们也能算出
算出了 由于是 是独立的,所以可以把 都从小到大排序,然后用一种所谓 "尺取法" 的东西(Atcoder题解叫这个,我感觉就是指针)
我们需要满足 ,我们把 从大到小枚举,然后令指针 指向 最小的节点,找到满足 最大的 ,那么对于这个 ,就有 个 满足条件
# Code
N, D = map(int, input().split())
x = [0] * N
y = [0] * N
for i in range(N):
x[i], y[i] = map(int, input().split())
M = 2 * 10 ** 6
def calc(x):
xsum = [0] * (2 * M + 1)
x.sort()
i = 0
xsum[-M] = sum(x) + N * M
for j in range(-M + 1, M + 1):
while i < N and x[i] < j:
i += 1
xsum[j] = xsum[j - 1] + 2 * i - N
return xsum
xsum = calc(x)
ysum = calc(y)
ans = 0
xsum.sort()
ysum.sort()
j = 0
for i in range(2 * M + 1)[::-1]:
while j < 2 * M + 1 and xsum[i] + ysum[j] <= D:
j += 1
ans += j
print(ans)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# F - Maximum Composition
# Question
给定 条线性函数 ,其中 。
对于一个由 个 不同的 整数 组成的序列,计算 的最大可能值,其中 的取值范围为 到 。
# Solution
先考虑 的等价条件
所以,我们按照 的标准,把 排序
现在我们排完序后有 个 我们需要从中选 个,这个就是一个很朴素的 DP 问题了
定义 对于前 ,已经选了 个的最优解,那么转移方程就是
答案就是
# Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
int main() {
int n, k; cin >> n >> k;
vector<int> a(n), b(n);
for (int i = 0; i < n; i++) cin >> a[i] >> b[i];
vector<int> ord(n);
for (int i = 0; i < n; i++) ord[i] = i;
sort(ord.begin(), ord.end(), [&](int i, int j) {
return b[i] * (a[j] - 1) > b[j] * (a[i] - 1);
});
vector<ll> dp(k + 1, -INF);
dp[0] = 1;
for (auto i : ord) {
auto ndp = dp;
for (int j = 0; j < k; j++) {
if (dp[j] != -INF) {
ndp[j + 1] = max(ndp[j + 1], dp[j] * a[i] + b[i]);
}
}
dp = ndp;
}
cout << dp[k] << endl;
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
上次更新: 2024/08/13, 14:34:37