感觉题目数据量出小了100倍,时间复杂度O(n^2),对于 100% 的数据,1 ≤ N ≤ 50。
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 map = new HashMap<> ();
HashMap size = new 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 map, int f1, int[] helpArray) {
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;
}
}