解题思路: 先合并两座岛各自的,然后在合并组合的 注意事项: 因为有多种组合,因此不要修改原并查集的数据 参考代码: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.*; public class Main { static PrintWriter out; static FastReader sc; static class FastReader { StringTokenizer st; BufferedReader br; public FastReader() { br = new BufferedReader (new InputStreamReader (System.in)); } String next() { while (st == null || !st.hasMoreElements ()) { try { st = new StringTokenizer (br.readLine ()); } catch (IOException e) { e.printStackTrace (); } } return st.nextToken (); } int nextInt() { return Integer.parseInt (next ()); } long nextLong() { return Long.parseLong (next ()); } double nextDouble() { return Double.parseDouble (next ()); } String nextLine() { String str = ""; try { str = br.readLine (); } catch (IOException e) { e.printStackTrace (); } return str; } } private static int maxArea = 0; public static void main(String[] args) { out = new PrintWriter (System.out); sc = new FastReader (); process合并区域 (); out.flush (); } public static void process合并区域() { boolean falg = true; int n = sc.nextInt (); maxArea = 0; int[][] map1 = new int[n][n], map2 = new int[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { map1[i][j] = sc.nextInt (); if (map1[i][j] == 1) { maxArea = 1; } } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { map2[i][j] = sc.nextInt (); if (map2[i][j] == 1) { maxArea = 1; } } } int ans = processUnion (n, map1, map2); out.println (ans); } private static int processUnion(int n, int[][] map1, int[][] map2) { int[] fa1 = new int[n * n], fa2 = new int[n * n]; int[] size1 = new int[n * n], size2 = new int[n * n]; if (map1[0][0] == 1) { fa1[0] = 0; size1[0] = 1; } if (map2[0][0] == 1) { fa2[0] = 0; size2[0] = 1; } for (int i = 1; i < n; i++) { if (map1[0][i] == 1) { fa1[i] = i; size1[i] = 1; if (map1[0][i - 1] == 1) { union (i - 1, i, fa1, size1); } } if (map2[0][i] == 1) { fa2[i] = i; size2[i] = 1; if (map2[0][i - 1] == 1) { union (i - 1, i, fa2, size2); } } } for (int i = 1; i < n; i++) { if (map1[i][0] == 1) { fa1[i * n] = i * n; size1[i * n] = 1; if (map1[i - 1][0] == 1) { union ((i - 1) * n, i * n, fa1, size1); } } if (map2[i][0] == 1) { fa2[i * n] = i * n; size2[i * n] = 1; if (map2[i - 1][0] == 1) { union (i * n - n, i * n, fa2, size2); } } for (int j = 1; j < n; j++) { if (map1[i][j] == 1) { fa1[i * n + j] = i * n + j; size1[i * n + j] = 1; if (map1[i - 1][j] == 1) { union ((i - 1) * n + j, i * n + j, fa1, size1); } if (map1[i][j - 1] == 1) { union (i * n + j - 1, i * n + j, fa1, size1); } } if (map2[i][j] == 1) { fa2[i * n + j] = i * n + j; size2[i * n + j] = 1; if (map2[i - 1][j] == 1) { union ((i - 1) * n + j, i * n + j, fa2, size2); } if (map2[i][j - 1] == 1) { union (i * n + j - 1, i * n + j, fa2, size2); } } } } //预处理旋转后可以组合的对象 int[][] me1 = new int[4][n], me2 = new int[4][n]; int[][] originfa1 = new int[4][n], originfa2 = new int[4][n]; for (int i = 0; i < n; i++) { me1[0][i] = map1[0][i]; originfa1[0][i] = findFather (fa1, i); me1[1][i] = map1[i][n - 1]; originfa1[1][i] = findFather (fa1, i * n + n - 1); me1[2][i] = map1[n - 1][n - 1 - i]; originfa1[2][i] = findFather (fa1, (n - 1) * n + n - 1 - i); me1[3][i] = map1[n - 1 - i][0]; originfa1[3][i] = findFather (fa1, (n - 1 - i) * n); me2[0][i] = map2[0][n - i - 1]; originfa2[0][i] = findFather (fa2, n - i - 1); me2[1][i] = map2[n - i - 1][n - 1]; originfa2[1][i] = findFather (fa2, (n - i - 1) * n + n - 1); me2[2][i] = map2[n - 1][i]; originfa2[2][i] = findFather (fa2, (n - 1) * n + i); me2[3][i] = map2[i][0]; originfa2[3][i] = findFather (fa2, i * n); } for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { processM (me1[i], me2[j], size1, size2, n, originfa1[i], originfa2[j]); } } return maxArea; } private static void processM(int[] map1, int[] map2, int[] size1, int[] size2, int n, int[] originfa1, int[] originfa2) { HashMap HashMap int[] helpArray = new int[n]; for (int i = 0; i < 2 * n - 1; i++) { map.clear (); size.clear (); int j = 0, k = 0; if (n - 1 - i >= 0) { j = n - 1 - i; } else { k = i + 1 - n; } for (; j < n && k < n; j++, k++) { if (map1[k] == 1 && map2[j] == 1) { int f1 = originfa1[k], f2 = originfa2[j] + 2500; if (!map.containsKey (f1)) { map.put (f1, f1); size.put (f1, size1[f1]); } if (!map.containsKey (f2)) { map.put (f2, f2); size.put (f2, size2[f2 - 2500]); } f1 = findFatherHash (map, f1, helpArray); f2 = findFatherHash (map, f2, helpArray); if (f1 != f2) { int cur = size.get (f1) + size.get (f2); maxArea = Math.max (cur, maxArea); size.put (f1, cur); map.put (f2, f1); } } } } } private static int findFatherHash(HashMap int index = -1; while (map.get (f1) != f1) { helpArray[++index] = f1; f1 = map.get (f1); } while (index >= 0) { map.put (helpArray[index--], f1); } return f1; } private static void union(int i, int j, int[] fa, int[] size) { int fa1 = findFather (fa, i); int fa2 = findFather (fa, j); if (fa1 != fa2) { int big = size[fa1] >= size[fa2] ? fa1 : fa2; int small = big == fa1 ? fa2 : fa1; size[big] += size[small]; maxArea = Math.max (maxArea, size[big]); fa[small] = big; } } private static int findFather(int[] fa, int i) { int t = i; while (i != fa[i]) { i = fa[i]; } while (t != i) { int temp = fa[t]; fa[t] = i; t = temp; } return i; } }
0.0分
2 人评分
矩阵转置 (C语言代码)浏览:1565 |
上车人数 (C语言代码)浏览:816 |
【魔板】 (C++代码)(时间超限,希望会的帮我改正一下)浏览:804 |
哥德巴赫曾猜测 (C语言代码)浏览:2560 |
C语言程序设计教程(第三版)课后习题5.5 (C语言代码)浏览:590 |
C语言程序设计教程(第三版)课后习题9.3 (C语言代码)浏览:750 |
JAM计数法 (C语言代码)浏览:721 |
2003年秋浙江省计算机等级考试二级C 编程题(1) (C语言代码)浏览:639 |
C语言程序设计教程(第三版)课后习题8.7 (C语言代码)浏览:538 |
小九九 (C++代码)简单粗暴,直接输出浏览:683 |