本文主要是介绍AtCoder Beginner Contest 327 题解 A-D,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
目录
- A - ab
- B - A^A
- C - Number Place
- D - Good Tuple Problem
A - ab
原题链接
题目描述
判断一个给定的字符串是否存在字符a
和字符b
相邻。
public static void solve() throws IOException{int a = readInt();String s = readString();boolean f = s.contains("ab") || s.contains("ba");printWriter.println(f ? "Yes" : "No");
}
B - A^A
原题链接
题目描述
给定一个整数B
,判断是否存在一个整数A
,使得 A A = B A^A=B AA=B,如果存在,输出 A A A,否则输出 − 1 -1 −1。
思路:枚举
public static void solve() throws IOException{long a = readLong();boolean f = false;for (int i = 1; i <= 100; i++) {long q = 1;for (int j = 1; j <= i; j++) {q *= i;}if (q == a) {printWriter.println(i);f = true;break;}if (q > a) break;}if (!f) {printWriter.println(-1);}
}
C - Number Place
原题链接
题目描述
给定义一个 9 × 9 9 \times 9 9×9 的二维矩阵,判断这个矩阵是否满足以下全部条件,如果满足输出Yes
,否则输出No
。
- 1 ∼ 9 1 \sim 9 1∼9的数字分别都在每行每列出现一次。
- 将该二维矩阵按顺序拆为 9 9 9 个 3 × 3 3 \times 3 3×3 的二维矩阵后, 1 ∼ 9 1 \sim 9 1∼9的数字分别都在每个矩阵出现一次。
思路:模拟+技巧
- 先判断每行每列是否满足条件。
- 再判断每个小二维矩阵是否满足条件。
public static void solve() throws IOException{int[][] map = utils.nextIntArray(9, 9);boolean f = true;// 判断行n = 9;for (int i = 1; i <= n; i++) {Set<Integer> set = new HashSet<>();for (int j = 1; j <= n; j++) {set.add(map[i][j]);}if (set.size() != 9) f = false;}// 判断列for (int i = 1; i <= n; i++) {Set<Integer> set = new HashSet<>();for (int j = 1; j <= n; j++) {set.add(map[j][i]);}if (set.size() != 9) f = false;}// 判断小圈int[] x = new int[] {1, 4, 7}, y = new int[] {3, 6, 9};for (int a = 0; a < 3; a++) {// 控制行for (int b = 0; b < 3; b++) {// 控制列Set<Integer> set = new HashSet<>();for (int i = 1; i <= n; i++) {for (int j = 1; j <= n; j++) {// 处于该小圈范围内if (i >= x[a] && i <= y[a] && j >= x[b] && j <= y[b]) {set.add(map[i][j]);}}}if (set.size() != 9) {f = false;break;}}}printWriter.println(f ? "Yes" : "No");
}
D - Good Tuple Problem
原题链接
题目描述
给定一个数组 S S S 和一个数组 T T T,长度都为 M M M。问是否存在一个长度为 N N N 的01
数组 X X X,使得 X S i ≠ X T i ( 1 ≤ i ≤ N ) X_{S_i} \neq X_{T_i}(1 \leq i \leq N) XSi=XTi(1≤i≤N),如果存在,输出Yes
,否则输出No
。
输入样例
3 3 1 2 3 2 3 1
输出样例
No
思路:并查集+技巧
- 这题仅问我们是否存在,而不要求求出序列 X X X,那么可以使用并查集,将 X X X 存在矛盾的两个位置记录下来,关键在于怎么维护存在矛盾的两个位置。
- 使用 N N N作为偏移量,每遍历到一对 S i S_i Si 和 T i T_i Ti 时,可以理解为都是在染色。
① 如果 p [ S i ] ≠ p [ T i ] p[S_i] \neq p[T_i] p[Si]=p[Ti],那么就分别更新他们的父节点为 f i n d ( T i + n ) find(T_i + n) find(Ti+n) 和 f i n d ( S i + n ) find(S_i + n) find(Si+n),表示 S i S_i Si不能和 f i n d ( T i + n ) find(T_i + n) find(Ti+n)染同一种颜色, T i T_i Ti不能和 f i n d ( S i + n ) find(S_i + n) find(Si+n)染同一种颜色。
② 如果 p [ S i ] = p [ T i ] p[S_i] = p[T_i] p[Si]=p[Ti],假设为 p p p,此时 S i S_i Si 不能和 p p p 染同一种颜色, T i T_i Ti不能和 p p p 染同一种颜色,但是 S i S_i Si 又不能和 T i T_i Ti 染同一种颜色,但是总共又只能染两种颜色,这时就出现了矛盾。
static int[] p;public static void solve() throws IOException{int n = readInt(), m = readInt();int[] s = new int[m + 1], t = new int[m + 1];for (int i = 1; i <= m; i++) s[i] = readInt();for (int i = 1; i <= m; i++) t[i] = readInt();p = new int[2 * n + 1];for (int i = 1; i <= 2 * n; i++) p[i] = i;boolean f = true;for (int i = 1; i <= m; i++) {int a = s[i], b = t[i];int pa = find(a), pb = find(b);if (pa == pb) {// 出现矛盾f = false;break;}p[pa] = find(b + n);p[pb] = find(a + n);}printWriter.println(f ? "Yes" : "No");
}public static int find(int x) {if (x != p[x]) {p[x] = find(p[x]);}return p[x];
}
这篇关于AtCoder Beginner Contest 327 题解 A-D的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!