Codeforces Round 937 (Div. 4)

A. Stair, Peak, or Neither?

思路:

  • 按照题目意思进行判断即可

时间复杂度:\(O(1)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void solve() {
int a[3];
for (int i = 0; i < 3; i++) {
std::cin >> a[i];
}

if (a[0] < a[1] && a[1] < a[2]) {
std::cout << "STAIR\n";
} else if (a[0] < a[1] && a[1] > a[2]) {
std::cout << "PEAK\n";
} else {
std::cout << "NONE\n";
}
}

B. Upscaling

思路:

  • C语言基础,利用 for 循环进行图形打印

时间复杂度:\(O(n^2)\)

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
34
35
36
37
38
39
40
41
42
43
44
void solve() {
int n;
std::cin >> n;

n <<= 1;

for (int l = 0, p = 0; l < n; l += 2, p++) {
if (p % 2 == 0) {
for (int m = 0; m < 2; m++) {
for (int i = 0, j = 0; i < n; i += 2, j++) {
if (j % 2 == 0) {
for (int k = 0; k < 2; k++) {
std::cout << '#';
}
} else {
for (int k = 0; k < 2; k++) {
std::cout << '.';
}
}
if (i + 2 == n) {
std::cout << "\n";
}
}
}
} else {
for (int m = 0; m < 2; m++) {
for (int i = 0, j = 0; i < n; i += 2, j++) {
if (j % 2 == 1) {
for (int k = 0; k < 2; k++) {
std::cout << '#';
}
} else {
for (int k = 0; k < 2; k++) {
std::cout << '.';
}
}
if (i + 2 == n) {
std::cout << "\n";
}
}
}
}
}
}

C. Clock Conversion

思路:

  • 基础数学换算题,就是取模输出,特判即可

时间复杂度:\(O(1)\)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void solve() {
int h, m;
scanf("%d:%d", &h, &m);

bool f = false;
if (h == 0) {
h += 12;
} else if (h == 12) {
f = true;
} else if (h > 12) {
f = true;
h %= 12;
}
if (f) {
printf("%02d:%02d PM\n", h, m);
} else {
printf("%02d:%02d AM\n", h, m);
}
}

D. Product of Binary Decimals

思路:

  • 由于由 0 或者 1 组成的数,且小于 \(10^5\) 的个数只有 31 个,所以直接暴搜即可

时间复杂度:\(O(31 \times logn \times depth)\)

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
i64 a[33] = {10, 11,
100, 101, 110, 111,
1000, 1001, 1010, 1011, 1101, 1100, 1111, 1110,
10000, 10001, 10010, 10011, 10100, 10101, 10110, 10111, 11000, 11001, 11010, 11011, 11100, 11101, 11110, 11111,
100000};
std::set<i64> st;

void solve() {
int n;
std::cin >> n;

bool f = true;
int t = n;
while (t) {
if ((t % 10 != 1) && (t % 10) != 0) {
f = false;
}
t /= 10;
}
if (f || st.count(n)) {
std::cout << "YES\n";
} else {
auto dfs = [&](auto self, i64 x) -> bool {
if (st.count(x)) return true;
for (auto v : st) {
if (x % v == 0) {
i64 t = x / v;
if (self(self, t)) {
return true;
}
}
}
return false;
};
if (dfs(dfs, 1LL * n)) {
std::cout << "YES\n";
} else {
std::cout << "NO\n";
}
}
}

signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);

int t;
std::cin >> t;

for (int i = 0; i < 31; i++) {
st.insert(a[i]);
}

while (t--) {
solve();
}

return 0;
}

E. Nearly Shortest Repeating Substring

思路:

  • 首先将字符串的长度 n 进行因数分解,这样可以保证,这个循环子串的长度一定累加的结果为 n
  • 然后分别从最前面和最后面判断是否可能出现一个长度为 x 的循环节,可以使得最终的子串只出现一个位置不相同

时间复杂度:\(O(n \times (logn + \sqrt n))\)

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
void solve() {
int n;
std::cin >> n;

std::string s;
std::cin >> s;

std::string t = std::string(s.rbegin(), s.rend()); // 方便倒着判断
std::vector<int> a;
for (int i = 1; i <= n / i; i++) {
if (n % i == 0) {
a.push_back(i);
a.push_back(n / i);
}
}
std::sort(a.begin(), a.end());

for (int x : a) {
auto check = [&](int v) {
int A = 0, B = A;
for (int i = x; i < n; i++) {
if (s[i % v] != s[i]) A++;
if (t[i % v] != t[i]) B++;
}
return A <= 1 || B <= 1;
};
if (check(x)) {
std::cout << x << "\n";
return ;
}
}
}

F. 0, 1, 2, Tree!

思路:

  • 看了 jiangly 的代码,就会发现自己写的好蠢
  • 直接一个宽搜,优先填二叉树的节点,然后填一个树的节点,我们直接每次搜树的高度,记录最后层树的高度,即为最小的树高

时间复杂度:\(O(2 \times a + b)\)

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
void solve() {
int a, b, c;
std::cin >> a >> b >> c;

if (c != a + 1) {
std::cout << -1 << "\n";
return;
}
std::queue<int> q;
q.push(0);
int ans = 0;
while (!q.empty()) {
int x = q.front();
q.pop();
ans = x;
if (a) {
a--;
q.push(x + 1);
q.push(x + 1);
} else if (b) {
b--;
q.push(x + 1);
}
}
std::cout << ans << "\n";
}