본문 바로가기

백준

C++[백준]14846번 직사각형과 쿼리

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

 

14846번: 직사각형과 쿼리

첫째 줄에 N (1 ≤ N ≤ 300)이 주어진다. 다음 N개의 줄에는 행렬의 정보가 주어지며, 각 줄은 N개의 수로 이루어져 있다. 행은 위에서부터 아래로, 열은 왼쪽부터 오른쪽으로 번호가 매겨져 있으며

www.acmicpc.net

 

솔루션


특정 인덱스(x,y)에서 1~10의 수를 몇개씩  갖고있는지 저장해둔다.

 

나는 구조체 내부에 배열을 선언하여, 1~10까지 몇 번 등장했는지, 저장해둔다.

 

특정 인덱스에서의 등장횟수를 찾는 법은

1. 현재 인덱스에 배열의 값을 ++

2. [x-1][y]에서의 등장 횟수 + [x][y-1]에서의 등장 횟수 - [x-1][y-1]에서의 등장횟수를 해 주면 특정 인덱스에서의 총 등장횟수를 알 수 있다.

 

그리고 각 쿼리에 대해서 값을 알아낼 땐,

 [x2][y2] 값에서 -[x2][y1-1] - [x1-1][y2] + [x1-1][y1-1]를 해 주면 구할 수 있다.

 

(누적합 매트릭스에서 자주 쓰이는 식이라.. 다른 곳에 찾아보면 이해하기 쉽게 적어 놓은 곳이 많을 것이다.)

 

 

 

코드


#include <iostream>
using namespace std;

struct pa {
	int value[11] = { 0, };

	void operator-=(const struct pa& t) {
		for (int i = 1; i <= 10; i++) {
			this->value[i] -= t.value[i];
		}
	}
	void operator+=(const struct pa& t) {
		for (int i = 1; i <= 10; i++) {
			this->value[i] += t.value[i];
		}
	}
};

int N;
struct pa dp[302][302];
int arr[302][302];

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	cin >> N;
	for (int i = 1; i <= N; i++) {
		for (int j = 1; j <= N; j++) {
			cin >> arr[i][j];
		}
	}

	dp[1][1].value[arr[1][1]]++;
	for (int i = 2; i <= N; i++) {
		dp[i][1].value[arr[i][1]]++;
		dp[i][1] += dp[i - 1][1];
		dp[1][i].value[arr[1][i]]++;
		dp[1][i] += dp[1][i - 1];
	}
	for (int i = 2; i <= N; i++) {
		for (int j = 2; j <= N; j++) {
			dp[i][j].value[arr[i][j]]++;
			dp[i][j] += dp[i - 1][j];
			dp[i][j] += dp[i][j - 1];
			dp[i][j] -= dp[i - 1][j - 1];
		}
	}

	int Q;
	cin >> Q;

	while (Q--) {
		int x1, y1, x2, y2;
		cin >> x1 >> y1 >> x2 >> y2;
		struct pa t = dp[x2][y2];

		t -= dp[x2][y1-1];
		t -= dp[x1-1][y2];
		t += dp[x1 - 1][y1 - 1];
		int cnt = 0;
		for (int i = 1; i <= 10; i++) {
			if (t.value[i] > 0) {
				cnt++;
			}
		}
		cout << cnt << '\n';
	}
}

 

'백준' 카테고리의 다른 글

C++[백준]1915번 가장 큰 정사각형  (0) 2023.06.23
C++[백준]22342번 계산 로봇  (0) 2023.06.23
C++[백준]1658번 돼지 잡기  (2) 2023.05.29
C++[백준]1996번 지뢰 찾기  (0) 2023.05.29
C++[백준] 1761번 정점들의 거리  (2) 2023.05.21