※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 12065번 문제인 gMatrix (Large)이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/12065
모든 "K행K열의 부분행렬에 적힌 수의 최댓값"의 합을 구하는 문제이다.
각 행의 모든 연속한 길이 K의 구간의 최댓값은 deque을 이용한 trick으로 선형 시간 복잡도에 전부 구할 수 있다. 이 값들을 다시 열 방향으로 살피면 연속한 길이 K의 구간에 대한 최댓값, 즉 K행K열의 부분행렬에 대한 최댓값을 빠르게 전부 구할 수 있다.
위 관찰을 이용해 문제를 해결하자.
아래는 제출한 소스코드이다.
#include <iostream>
#include <deque>
#include <vector>
using namespace std;
typedef long long ll;
int N, K, CC, X;
int R[3001], C[3001];
int A[3001][3001];
deque<pair<int, int>> dq[3001]; // {최댓값, 열}
void solve() {
ll ans = 0;
cin >> N >> K >> CC >> X;
for (int i = 1; i <= N; i++) cin >> R[i];
for (int i = 1; i <= N; i++) cin >> C[i];
for (int r = 1; r <= N; r++) {
for (int c = 1; c <= N; c++) {
A[r][c] = ((ll)R[r] * r + (ll)C[c] * c + CC) % X;
}
}
for (int r = 1; r <= N; r++) {
auto &dque = dq[r];
dque.clear();
for (int c = 1; c < K; c++) {
int val = A[r][c];
while (!dque.empty() && dque.back().first <= val) dque.pop_back();
dque.push_back(make_pair(val, c));
}
}
for (int c = K; c <= N; c++) {
deque<pair<int, int>> dqdq;
for (int r = 1; r < K; r++) {
auto &dque = dq[r];
int val = A[r][c];
while (!dque.empty() && dque.back().first <= val) dque.pop_back();
dque.push_back(make_pair(val, c));
while (dque.front().second + K <= c) dque.pop_front();
val = dque.front().first;
while (!dqdq.empty() && dqdq.back().first <= val) dqdq.pop_back();
dqdq.push_back(make_pair(val, r));
}
for (int r = K; r <= N; r++) {
auto &dque = dq[r];
int val = A[r][c];
while (!dque.empty() && dque.back().first <= val) dque.pop_back();
dque.push_back(make_pair(val, c));
while (dque.front().second + K <= c) dque.pop_front();
val = dque.front().first;
while (!dqdq.empty() && dqdq.back().first <= val) dqdq.pop_back();
dqdq.push_back(make_pair(val, r));
while (dqdq.front().second + K <= r) dqdq.pop_front();
ans += dqdq.front().first;
}
}
cout << ans << '\n';
}
int T;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> T;
for (int t = 1; t <= T; t++) {
cout << "Case #" << t << ": ";
solve();
}
}
728x90
'BOJ' 카테고리의 다른 글
[BOJ 16203 // C++] 까다로운 수 찾기 (0) | 2024.07.22 |
---|---|
[BOJ 16132 // C++] 그룹 나누기 (Subset) (0) | 2024.07.21 |
[BOJ 8478 // C++] Chessboard (0) | 2024.07.19 |
[BOJ 24649 // C++] Letters Q and F (0) | 2024.07.18 |
[BOJ 11541 // C++] At most twice (1) | 2024.07.17 |