URL:https://atcoder.jp/contests/abc312
目录
A
Problem/题意
Thought/思路
模拟。
Code/代码
#include "bits/stdc++.h"
signed main() <%
std::string s<:10:> = <%"ACE", "BDF", "CEG", "DFA", "EGB", "FAC", "GBD"%>;
std::string x; std::cin >> x;
for (int i = 0; i < 7; ++ i) {
if (x == s<:i:>) {
std::cout << "Yes";
return 0;
}
}
std::cout << "No";
return 0;
%>
B
Problem/题意
对于一个 9 * 9 的矩阵,左上角要求是一个 3 * 3 的黑矩阵,右下角也是一个 3 * 3 的黑矩阵,且他们的边缘要求是白色的。
Thought/思路
模拟。
Code/代码
#include "bits/stdc++.h"
int n, m;
char mp<:107:><:107:>;
char m1<:6:><:6:> = {
"###.",
"###.",
"###.",
"...."
};
char m2<:6:><:6:> = {
"....",
".###",
".###",
".###"
};
bool check(int x, int y) {
//std::cout << "=======\n";
bool res = true;
for (int i = 0; i <= 3; ++ i) {
for (int j = 0; j <= 3; ++ j) {
//std::cout << m1[i][j] << " " << mp[x + i][y + j] << "\n";
if (m1[i][j] != mp[x + i][y + j]) res = false;
}
}
//std::cout << "--------\n";
for (int i = 0; i <= 3; ++ i) {
for (int j = 0; j <= 3; ++ j) {
//std::cout << m2[i][j] << " " << mp[x + i][y + j] << "\n";
if (m2[i][j] != mp[x + i + 5][y + j + 5]) res = false;
}
}
//std::cout << "=======\n";
return res;
}
signed main() <%
std::cin >> n >> m;
for (int i = 1; i <= n; ++ i) <%
for (int j = 1; j <= m; ++ j) <%
std::cin >> mp<:i:><:j:>;
%>
%>
for (int i = 1; i <= n - 8; ++ i) <%
for (int j = 1; j <= m - 8; ++ j) <%
if (check(i, j)) {
std::cout << i << " " << j << "\n";
}
%>
%>
%>
C
Problem/题意
有 N 个卖家,他们出售苹果的最低售价是 Ai。
有 M 个买家,他们购买苹果的最高预期是 Bi。
求一个最小的 X,使得能出这个价格的卖家数量大于等于能出这个价格的买家数量。
Thought/思路
二分 X。
Code/代码
#include "bits/stdc++.h"
int n, m, a[200007], b[200007];
bool check(int x) {
int num_a = 0, num_b = 0;
for (int i = 1; i <= n; ++ i) if (a[i] <= x) num_a ++;
for (int i = 1; i <= m; ++ i) if (b[i] >= x) num_b ++;
if (num_a >= num_b) return true;
else return false;
}
signed main() {
std::cin >> n >> m;
for (int i = 1; i <= n; ++ i) std::cin >> a[i];
for (int j = 1; j <= m; ++ j) std::cin >> b[j];
int l = 0, r = 1e9 + 7;
while (l + 1 != r) {
int mid = (l + r) >> 1;
if (check(mid)) r = mid;
else l = mid;
}
std::cout << r;
}
D
Problem/题意
给一个由()?组成的字符串,将?转换为()后能有多少种合法方案。
Thought/思路
合法的括号序列显然要满足,左到右的每个位置,(的数量不少于)的数量,且最后两者数量相等。
基于此,我们定义 dp[i][j] 为,前 i 个字符中,左括号数量为 j 个的合法方案数。
当 s[i] = '(' 时,可以直接转移;
当 s[i] = ')' 时,需要判断当前的左括号数量是否大于等于右括号数量。
最后就是输出 dp[n][n / 2]。
Code/代码
#include "bits/stdc++.h"
const int mod = 998244353;
int dp[3007][3007];
signed main() {
std::string s; std::cin >> s;
int n = s.length();
dp[0][0] = 1;
s = "#" + s;
for (int i = 1; i <= n; ++ i) {
for (int j = 1; j <= i; ++ j) {
if (s[i] == '(') {
dp[i][j] = dp[i - 1][j - 1];
} else if (s[i] == ')') {
if (j >= i - j) dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j - 1];
if (j >= i - j) dp[i][j] = (dp[i][j] + dp[i - 1][j]) % mod;
}
}
}
std::cout << dp[n][n / 2] % mod;
}
E
Problem/题意
给定 n 个没有相交的正方体,对于每个正方体,问它与多少个正方体会有面的相切。
Thought/思路
不会,这是别人的思路(取自~Lanly~):
Code/代码
#include "bits/stdc++.h"
int n, to[107][107][107];
signed main() {
std::cin >> n;
for (int i = 1; i <= n; ++ i) {
std::array <int, 6> p;
for (auto &j : p) std::cin >> j;
for (int x = p[0]; x < p[3]; ++ x) {
for (int y = p[1]; y < p[4]; ++ y) {
for (int z = p[2]; z < p[5]; ++ z) {
to[x][y][z] = i;
}
}
}
}
std::vector <std::set <int>> st(n + 1);
for (int i = 0; i < 100; ++ i) {
for (int j = 0; j < 100; ++ j) {
for (int k = 0; k < 100; ++ k) {
int o = to[i][j][k];
int a = to[i + 1][j][k], b = to[i][j + 1][k], c = to[i][j][k + 1];
if (o == 0) continue;
if (a and a != o) {
st[o].insert(a);
st[a].insert(o);
}
if (b and b != o) {
st[o].insert(b);
st[b].insert(o);
}
if (c and c != o) {
st[o].insert(c);
st[c].insert(o);
}
}
}
}
for (int i = 1; i <= n; ++ i) std::cout << st[i].size() << "\n";
return 0;
}