728x90

문제

 

 

접근 방식

1인 부분으로만 이루어진 정사각형 중 가장 큰 정사각형을 찾아야 한다.

1

11
11

111
111
111

 

위와 같이 1로만 이루어진 곳을 찾아야 하는데

1인 곳을 발견할 때마다 주변을 한 칸씩 넓혀가며 모두 1인지 확인하는 것은

시간초과가 날 것이 확실하기 때문에 그렇게 무식하게 풀 수는 없다.

00
01

 

위의 경우를 생각해보면 1 주변은 모두 0이기 때문에 정사각형이 될 수 없고

크기가 1인 정사각형 하나만 가능하다.

11
11 <

 

위의 경우라면 오른쪽 맨 아래의 1을 기준으로 주변 3개가 모두 1이니

크기가 4인 정사각형을 만들 수 있다.

01
11

 

하지만 위와 같이 하나라도 1이 아니라면 각각 크기가 1인 정사각형만 만들 수 있고

결국 자기 주변의 칸들이 모두 1이라면 길이가 1 더 긴 정사각형을 만들 수 있다는 것이다.

0111
0111
0111

 

위의 경우를 예시로 DP 테이블을 채우는 과정을 살펴보면 아래와 같다.

01

011

0111

0111
0

0111
01

0111
012

0111
0122

0111
0122
0

0111
0122
01

0111
0122
012

0111
0122
0122

 

첫 행과 열에 등장한 1은 위나 옆을 살펴볼 수 없으니 무조건 1이 될 것이고

이후에 등장한 1들은 주변 3칸을 살펴봐서 모두 1이라면

기존보다 길이가 1긴 정사각형을 만들 수 있으니 0 > 1 > 2 ... > n 순으로

길이를 늘려주기만 하면 된다.

 

풀이

public class Main {

	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] input = br.readLine().split(" ");

		int n = Integer.parseInt(input[0]);
		int m = Integer.parseInt(input[1]);
		int max = 0;

		int[][] dp = new int[n][m];
		int[] dx = {-1, -1, 0};
		int[] dy = {-1, 0, -1};

		for (int i = 0; i < n; i++) {
			input = br.readLine().split("");
			for (int j = 0; j < m; j++) {
				if (Integer.parseInt(input[j]) != 1) continue;

				int min = Integer.MAX_VALUE;

				for (int dir = 0; dir < 3; dir++) {
					int x = i + dx[dir];
					int y = j + dy[dir];

					if (x < 0 || y < 0) {
						min = 0;
						break;
					}

					min = Math.min(min, dp[x][y]);
				}

				dp[i][j] = min + 1;
				max = Math.max(max, dp[i][j]);
			}
		}

		System.out.println(max * max);
	}
}

 

'Java > Algorithms' 카테고리의 다른 글

[백준] 2011번 : 암호코드  (0) 2024.03.19
[백준] 10942번 : 팰린드롬?  (0) 2024.03.18
[백준] 2294번 : 동전2  (0) 2024.03.16
[백준] 9084번 : 동전  (0) 2024.03.16
[백준] 9657번 : 돌 게임 3  (1) 2024.03.13

+ Recent posts