※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※

 

이번에 볼 문제는 백준 5549번 문제인 행성 탐사이다.
문제는 아래 링크를 확인하자.

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

 

5549번: 행성 탐사

상근이는 우주선을 타고 인간이 거주할 수 있는 행성을 찾고 있다. 마침내, 전 세계 최초로 인간이 거주할 수 있는 행성을 찾았다. 이 행성은 정글, 바다, 얼음이 뒤얽힌 행성이다. 상근이는 이

www.acmicpc.net

1행1열부터 r행c열까지의 'J'의 개수를 \(dp[r][c]\)라 하자. r행c열에 적힌 문자가 'J'인 경우 \(dp[r][c] = dp[r-1][c] + dp[r][c-1] - dp[r-1][c-1] + 1\), 그렇지 않은 경우 \(dp[r][c] = dp[r-1][c] + dp[r][c-1] - dp[r-1][c-1]\)이 성립함을 이용하면 모든 \(dp[r][c]\)의 값을 \(O(RC)\)에 계산해낼 수 있다. 이는 'O' 및 'I'에 대해서도 마찬가지이다.

 

위와 점화식과 같은 원리의 식을 이용하면 위에서 구한 값들을 이용해 주어지는 쿼리의 답을 각 쿼리당 \(O(1)\)의 시간복잡도로 구해낼 수 있다. 이를 통해 문제를 해결하자.

 

아래는 제출한 소스코드이다.

#include <iostream>
#include <string>
using namespace std;
typedef long long ll;

int R, C, Q;
string board[1000];

int psumJ[1001][1001];
int psumO[1001][1001];
int psumI[1001][1001];

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> R >> C >> Q;
	for (int r = 0; r < R; r++) cin >> board[r];

	for (int r = 0; r < R; r++) {
		for (int c = 0; c < C; c++) {
			psumJ[r + 1][c + 1] = psumJ[r][c + 1] + psumJ[r + 1][c] - psumJ[r][c];
			psumO[r + 1][c + 1] = psumO[r][c + 1] + psumO[r + 1][c] - psumO[r][c];
			psumI[r + 1][c + 1] = psumI[r][c + 1] + psumI[r + 1][c] - psumI[r][c];

			if (board[r][c] == 'J') psumJ[r + 1][c + 1]++;
			else if (board[r][c] == 'O') psumO[r + 1][c + 1]++;
			else psumI[r + 1][c + 1]++;
		}
	}

	while (Q--) {
		int r1, c1, r2, c2; cin >> r1 >> c1 >> r2 >> c2;
		cout << psumJ[r2][c2] - psumJ[r1 - 1][c2] - psumJ[r2][c1 - 1] + psumJ[r1 - 1][c1 - 1] << ' ';
		cout << psumO[r2][c2] - psumO[r1 - 1][c2] - psumO[r2][c1 - 1] + psumO[r1 - 1][c1 - 1] << ' ';
		cout << psumI[r2][c2] - psumI[r1 - 1][c2] - psumI[r2][c1 - 1] + psumI[r1 - 1][c1 - 1] << '\n';
	}
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 16681 // C++] 등산  (0) 2023.06.28
[BOJ 1398 // C++] 동전 문제  (0) 2023.06.27
[BOJ 1023 // C++] 괄호 문자열  (0) 2023.06.25
[BOJ 1138 // C++] 한 줄로 서기  (0) 2023.06.24
[BOJ 1103 // C++] 게임  (0) 2023.06.23

+ Recent posts