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

 

이번에 볼 문제는 백준 24450번 문제인 国土分割 (Land Division)이다.
문제는 아래 링크를 확인하자.

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

 

24450번: 国土分割 (Land Division)

JOI 国は縦 H 行,横 W 列のマス目状に区切られた長方形の形をしている.JOI 国の縦方向は南北方向に平行であり,横方向は東西方向に平行である.北から i 行目 (1 ≦ i ≦ H),西から j 

www.acmicpc.net

가로선과 세로선을 동시에 그어 국토분할이 제대로 이루어진 경우를 생각해보면, 각 분할된 칸 안에 적힌 수의 합이 각각 같은 상황이라는 의미이므로 가로선만으로 분할된 국토 및 세로선만으로 분할된 국토들도 각 분할에 적힌 수의 합이 같게 된다. 즉, 가로선과 세로선을 동시에 그어 국토분할이 이루어지는 경우의 수는 가로선만으로 분할할 수 있는 방법들과 세로선만으로 분할할 수 있는 방법들의 조합만을 살펴 실제로 분할이 이루어지는지를 확인해보는 것으로 계산해낼 수 있게 된다.

 

따라서, 가로선만을 긋는 방법과 세로선만을 긋는 방법들을 먼저 찾아내고 두 방법의 조합별로 선을 그었을 때 분할이 제대로 이루어지는지를 체크하는 것으로 문제를 해결할 수 있다.

 

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

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

int R, C;
ll board[51][51];
ll rsum[51], csum[51], total = 0;
vector<vector<int>> rpartition, cpartition;

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

	cin >> R >> C;
	for (int r = 1; r <= R; r++) {
		for (int c = 1; c <= C; c++) {
			ll& x = board[r][c];
			cin >> x;
			rsum[r] += x, csum[c] += x, total += x;
		}
	}

	for (int k = 1; k <= R; k++) { // row들을 k개로 partition
		if (total % k) continue;
		ll val = total / k;
		ll psum = 0;
		bool chk = 1;
		vector<int> partition;
		for (int r = 1; r <= R; r++) {
			psum += rsum[r];
			if (psum > val) {
				chk = 0;
				break;
			}
			else if (psum == val) {
				partition.emplace_back(r);
				psum = 0;
			}
		}

		if (chk) rpartition.emplace_back(partition);
	}
	for (int k = 1; k <= C; k++) { // col들을 k개로 partition
		if (total % k) continue;
		ll val = total / k;
		ll psum = 0;
		bool chk = 1;
		vector<int> partition;
		for (int c = 1; c <= C; c++) {
			psum += csum[c];
			if (psum > val) {
				chk = 0;
				break;
			}
			else if (psum == val) {
				partition.emplace_back(c);
				psum = 0;
			}
		}

		if (chk) cpartition.emplace_back(partition);
	}

	int ans = 0;
	for (auto& rp : rpartition) {
		for (auto& cp : cpartition) {
			int rsize = rp.size(), csize = cp.size();
			int k = rsize * csize;
			if (total % k) continue;

			ll val = total / k;
			bool chk = 1;
			int oldr = 1;
			for (auto& r : rp) {
				int oldc = 1;
				for (auto& c : cp) {
					ll tmp = 0;
					for (int rr = oldr; rr <= r; rr++) {
						for (int cc = oldc; cc <= c; cc++) {
							tmp += board[rr][cc];
						}
					}
					if (tmp != val) chk = 0;
					oldc = c + 1;
				}
				oldr = r + 1;
			}
			if (chk) ans++;
		}
	}

	cout << ans - 1;
}
728x90

'BOJ' 카테고리의 다른 글

[BOJ 5357 // C++] Dedupe  (0) 2022.12.19
[BOJ 26561 // C++] Population  (0) 2022.12.19
[BOJ 6825 // C++] Body Mass Index  (0) 2022.12.19
[BOJ 26531 // C++] Simple Sum  (0) 2022.12.19
[BOJ 2321 // Fortran] Crowing  (0) 2022.12.19

+ Recent posts