AtCoder Beginner Contest 232题解

M-SOLUTIONS Programming Contest 2021(AtCoder Beginner Contest 232)

A - QQ solver

题意:自己看题目

思路:根据题意模拟即可

参考代码:

#include<bits/stdc++.h>
using namespace std;
string s;
int main() {
	cin >> s;
	int a = s[0] - '0', b = s[2] - '0';
	cout << a * b << endl;
	return 0;
}

B - Caesar Cipher

题意:给你两个长度都为\(n\)且都由小写字母组成的串\(s\) , \(t\),如果存在一个确定的非负整数\(k\)使得对于所有的\(1 \leq i \leq n\)有\(s[i] + k = t[i]\),需要特别说明的是\('z' + 1 = 'a'\) 。

思路:

​ 方法一:考虑到\(k\)最大不会超过\(26\),所以可以从\(0\)开始枚举检验到\(26\),看是否存在符合条件的\(k\)值,时间复杂度是\(O(26n)\)。

​ 方法二: 考虑到这个加法是在模\(26\)意义下进行的,所以可以对\(s\)和\(t\)的每一项做差然后模\(26\)看所有的差值是否相同,相同就是存在,不相同就是不存在。

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

参考代码:

string s, t;
void solve() {
	cin >> s >> t;
	int dx = (s[0] - t[0] + 26) % 26;
	int n = s.size();
	for (int i = 1; i < n; ++i) {
		int dy = (s[i] - t[i] + 26) % 26;
		if (dx != dy) {
			puts("No");
			return;
		}
	}
	puts("Yes");
	return;
}

C - Graph Isomorphism

题意:给你两个有\(n\)个点和\(m\)条边的无向图\(A\)和\(B\),问你这两个图的形状是否相同,形状相同的定义为:

存在一个长度为\(n\)的排列\(P\),使得对于任意的\(i\),\(j\),都满足\(A_{i , j} = B_{p_i , p_j}\)

思路:考虑到这题的数据范围\(1 \leq n \leq 8\) 所以考虑直接暴力枚举每一个排列进行检验即可

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

参考代码:

const int N = 9;
int a[N][N], b[N][N];
int p[N], n, m, u, v;
void solve() {
	cin >> n >> m;
	for (int i = 1; i <= m; ++i) {
		cin >> u >> v;
		a[u][v] = a[v][u] = 1;
	}
	for (int i = 1; i <= m; ++i) {
		cin >> u >> v;
		b[u][v] = b[v][u] = 1;
	}
	for (int i = 1; i <= n; ++i) p[i] = i;
	do {
		bool res = true;
		for(int i = 1 ; i <= n && res; ++i)
			for (int j = 1; j <= n && res; ++j) {
				if (a[i][j] != b[p[i]][p[j]]) res = false;
			}
		if (res) {
			puts("Yes");
			return;
		}
	} while (next_permutation(p + 1, p + 1 + n));
	puts("No");
	return;
}

D - Weak Takahashi

题意:有一个\(H \times W\)的网格,\((i , j)\)表示第\(i\)行\(j\)列,\(C_{i , j} = '.'\)表示空地,\(C_{i , j} = '\#'\) 表示墙,你从\((1 , 1)\)开始,每次只能向下走或者向右走,但不能走到墙所在的位置,问你能走到最大的空地的数量。

思路:考虑倒着做,也就变成你可以以任意点作为起点,每次只能向左走或者向上走,走到\((1 , 1)\)所经过的空地的最大数量,转移方程为:

\[f_{i , j} = max(f_{i + 1 , j} , f_{i , j + 1}) + 1 \;\; c_{i , j} != '\#' \]

时间复杂度:\(O(H \times W)\)

参考代码:

const int N = 105;
char strs[N][N];
int n, m;
int f[N][N];
void solve() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) cin >> strs[i] + 1;
	for(int i = n ; i >= 1 ; --i)
		for (int j = m; j >= 1; --j) {
			if (strs[i][j] == '#') continue;
			f[i][j] = max(f[i + 1][j], f[i][j + 1]) + 1;
		}
	cout << f[1][1] << '\n';
	return;
}
上一篇:Atcoder Regular Contest 063 D - Snuke's Coloring 2(单调栈+线段树)


下一篇:AtCoder Educational DP Contest