본문 바로가기
PS/BOJ

백준 1028 / C++

by jaehoonChoi 2022. 8. 12.

https://www.acmicpc.net/problem/1028

 

1028번: 다이아몬드 광산

첫째 줄에 R과 C가 주어진다. R과 C는 750보다 작거나 같은 자연수이다. 둘째 줄부터 R개의 줄에는 다이아몬드 광산의 모양이 주어진다.

www.acmicpc.net

 

[ 풀이 ]

한 점 (i,j)에서 왼쪽아래, 오른쪽 아래 대각선으로 최대로 긴 연속된 1의 개수를 저장해놓자. 

다이아몬드의 비교는 한 점을 기준으로 min(왼쪽, 오른쪽)을 찾고 그 사이의 길이에 대해 탐색해주면 된다.

시간복잡도는 O(N^3/2)정도 된다. 

 

[ Code ] 

#include <bits/stdc++.h>
using namespace std;
int n, m, a[777][777], dp[2][777][777];

int solve(int i, int j) {
	// 최대 길이
	int l = min(dp[0][i][j], dp[1][i][j]) - 1;
	if (l < 0) return 0;
	int ret = 1;
	// 그 길이보다 작은 모두 경우 탐색 
	for (int k = 1; k <= l; k++) {
		if (i + k > n || j + k > m || j - k < 1) continue;
		if (min(dp[1][i + k][j - k], dp[0][i + k][j + k]) >= k + 1) {
			ret = k + 1;
		}
	}
	return ret;
}

int main() {
	ios::sync_with_stdio(0), cin.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			char x; cin >> x;
			a[i][j] = x - '0';
		}
	}
	for (int i = n; i >= 1; i--) {
		for (int j = m; j >= 1; j--) {
			if (a[i][j]) {
				// 왼쪽 대각선 
				dp[0][i][j] = dp[0][i + 1][j - 1] + 1;
				// 오른쪽 대각선 
				dp[1][i][j] = dp[1][i + 1][j + 1] + 1;
			}
			else {
				dp[0][i][j] = 0;
				dp[1][i][j] = 0;
			}
		}
	}
	int ans = 0;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			ans = max(ans, solve(i, j));
		}
	}
	cout << ans;
}

'PS > BOJ' 카테고리의 다른 글

백준 14398 / C++  (0) 2022.08.17
백준 11670 / C++  (0) 2022.08.17
백준 1493 / C++  (0) 2022.08.12
백준 11616 / C++  (0) 2022.08.12
백준 12911 / C++  (0) 2022.08.12

댓글