제출 #260744

#제출 시각아이디문제언어결과실행 시간메모리
260744idk321Rectangles (IOI19_rect)Java
15 / 100
5220 ms1048576 KiB
import java.util.Arrays;

class rect {
	boolean[][] visited;

	public long count_rectangles(int[][] a) {
		int n = a.length;
		int m = a[0].length;
		int[][] dpUp = new int[n][m];
		int[][] dpDown = new int[n][m];
		int[][] dpLeft = new int[n][m];
		int[][] dpRight = new int[n][m];

		for (int i = 1; i < n - 1; i++) {
			for (int j = m - 2; j > 0; j--) {
				if (a[i - 1][j] > a[i][j]) dpUp[i][j] = dpUp[i][j + 1] + 1;
				if (a[i + 1][j] > a[i][j]) dpDown[i][j] = dpDown[i][j + 1] + 1;
			}
		}
		for (int i = n - 2; i > 0; i--) {
			for (int j = 1; j < m - 1; j++) {
				if (a[i][j + 1] > a[i][j]) dpRight[i][j] = dpRight[i + 1][j] + 1;
				if (a[i][j - 1] > a[i][j]) dpLeft[i][j] = dpLeft[i + 1][j] + 1;
			}
		}

		if (n <= 2 || m <= 2) return 0;

		boolean allZeroAndOne = true;
		for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) if (a[i][j] != 0 && a[i][j] != 1) allZeroAndOne = false;

		if (n <= 3) {
			int currLength = 0;
			int goodStarts = 0;
			long res = 0;
			for (int i = 1; i < m - 1; i++) {
				int h = a[1][i];
				if (a[0][i] <= h || a[2][i] <= h) {
					goodStarts = 0;
				} else {
					if (a[1][i - 1] > h) goodStarts++;
					if (a[1][i + 1] > h) res += goodStarts;
				}
			}

			return res;
		/*} else if (allZeroAndOne) {
			visited = new boolean[n][m];
			Arrays.fill(visited[0], true);
			Arrays.fill(visited[n - 1], true);
			for (int i = 0; i < n; i++) {
				visited[i][0] = true;
				visited[i][m - 1] = true;
			}
			for (int i = 1; i < n - 1; i++) {
				for (int j = 1; j < m - 1; j++) {

				}
			} */
		} else {
			int[][][] maxRight = new int[n][m][m];
			for (int i = 1; i < n - 1; i++) {
				for (int j = 1; j < m - 1; j++) {
					for (int k = j; k < m - 1; k++) {
						if (j == k) {
							maxRight[i][j][k] = a[i][j];
						} else {
							maxRight[i][j][k] = Math.max(a[i][k], maxRight[i][j][k - 1]);
						}
					}
				}
			}
			int[][][] maxDown = new int[m][n][n];
			for (int j = 1; j < m - 1; j++) {
				for (int i = 1; i < n - 1; i++) {
					for (int k = i; k < n - 1; k++) {
						if (i == k) {
							maxDown[j][i][k] = a[i][j];
						} else {
							maxDown[j][i][k] = Math.max(a[k][j], maxDown[j][i][k - 1]);
						}
					}
				}
			}

			boolean[][][][] okJ = new boolean[n][n][m][m];
			for (int i = 1; i < n - 1; i++) {
				for (int k = i; k < n - 1; k++) {
					for (int j = 1;  j < m - 1; j++) {
						for (int l = j; l < m - 1; l++) {
							okJ[i][k][j][l] = maxRight[k][j][l] < a[k][l + 1] && maxRight[k][j][l] < a[k][j - 1];
							if (k != i) {
								okJ[i][k][j][l] = okJ[i][k][j][l] && okJ[i][k - 1][j][l];
							}
						}
					}
				}
			}
			boolean[][][][] okI = new boolean[n][n][m][m];
			for (int i = 1; i < n - 1; i++) {
				for (int k = i; k < n - 1; k++) {
					for (int j = 1;  j < m - 1; j++) {
						for (int l = j; l < m - 1; l++) {
							okI[i][k][j][l] = maxDown[l][i][k] < a[i - 1][l] && maxDown[l][i][k] < a[k + 1][l];
							if (j != l) {
								okI[i][k][j][l] = okI[i][k][j][l] && okI[i][k][j][l - 1];
							}
						}
					}
				}
			}


			long rect = 0;
			for (int i = 1; i < n - 1; i++) {
				for (int j = 1; j < m - 1; j++) {
					for (int k = i; k < n - 1; k++) {
						if (a[k][j - 1] <= a[k][j]) break;
						for (int l = j; l < m - 1; l++) {
							if (maxDown[l][i][k] >= a[k + 1][l]) break;
							if (maxDown[l][i][k] >= a[i - 1][l]) break;


 							if (okI[i][k][j][l] && okJ[i][k][j][l]) {
								rect++;
								//System.out.println(i + " " + j + " " + k + " " + l);
							}
						}
					}
				}
			}
			//System.out.println(Arrays.deepToString(maxDown));
			//System.out.println(Arrays.deepToString(rightOk));
			//System.out.println(maxDown[1][1][1]);

			return rect;
		}
	}


	private boolean checkIfGood(int[][] ar, int a, int b, int c, int d) {

		for (int i = a; i <= c; i++) {
			int max = 0;
			for (int j = b; j <= d; j++) {
				max = Math.max(max, ar[i][j]);
			}
			if (ar[i][d + 1] <= max) return false;
			if (ar[i][b - 1] <= max) return false;
		}
		for (int j = b; j <= d; j++) {
			int max = 0;
			for (int i = a; i <= c; i++) {
				max = Math.max(max, ar[i][j]);
			}
			if (ar[c + 1][j] <= max) return false;
			if (ar[a - 1][j] <= max) return false;
		}

		return true;
	}
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...