๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๋ฐฑ์ค€/Gold

[BOJ] 21609 : ์ƒ์–ด ์ค‘ํ•™๊ต

by Jaeguk 2022. 6. 2.
๋ฌธ์ œ ๋งํฌ

21609๋ฒˆ: ์ƒ์–ด ์ค‘ํ•™๊ต (acmicpc.net)

 

21609๋ฒˆ: ์ƒ์–ด ์ค‘ํ•™๊ต

์ƒ์–ด ์ค‘ํ•™๊ต์˜ ์ฝ”๋”ฉ ๋™์•„๋ฆฌ์—์„œ ๊ฒŒ์ž„์„ ๋งŒ๋“ค์—ˆ๋‹ค. ์ด ๊ฒŒ์ž„์€ ํฌ๊ธฐ๊ฐ€ N×N์ธ ๊ฒฉ์ž์—์„œ ์ง„ํ–‰๋˜๊ณ , ์ดˆ๊ธฐ์— ๊ฒฉ์ž์˜ ๋ชจ๋“  ์นธ์—๋Š” ๋ธ”๋ก์ด ํ•˜๋‚˜์”ฉ ๋“ค์–ด์žˆ๊ณ , ๋ธ”๋ก์€ ๊ฒ€์€์ƒ‰ ๋ธ”๋ก, ๋ฌด์ง€๊ฐœ ๋ธ”๋ก, ์ผ๋ฐ˜ ๋ธ”๋ก

www.acmicpc.net

์ƒ์–ด ์ดˆ๋“ฑํ•™๊ต์— ์ด์–ด์„œ ์ƒ์–ด ์ค‘ํ•™๊ต ๋ฌธ์ œ. ์—ญ์‹œ ๊ตฌํ˜„๋ฌธ์ œ๋‹ค.

ํ’€์ด

N x N์œผ๋กœ ์ฃผ์–ด์ง„ ๊ฒฉ์ž๋ฅผ ์ฃผ์–ด์ง„ ๊ณผ์ •์— ๋”ฐ๋ผ ๋ธ”๋ก๊ทธ๋ฃน์„ ์‚ญ์ œํ•˜๋Š” ๊ฒŒ์ž„.

์ตœ์ข… ์ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜์ž.

๋ธ”๋ก ๊ทธ๋ฃน์—๋Š” ๋ฐ˜๋“œ์‹œ ๊ฐ™์€ ์ƒ‰๊น”์˜ ๋ธ”๋ก๋“ค์ด ํฌํ•จ๋˜์–ด์•ผํ•˜๋ฉฐ, ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์€ ์–ด๋Š ๊ทธ๋ฃน์—๋‚˜ ํฌํ•จ๋  ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฒ€์€์ƒ‰ ๋ธ”๋ก์€ ์–ด๋–ค ๊ทธ๋ฃน์—๋„ ๋“ค์–ด๊ฐˆ ์ˆ˜ ์—†๋‹ค. ์ด๋•Œ ๋ธ”๋ก๊ทธ๋ฃน์— ์ผ๋ฐ˜ ๋ธ”๋ก์ด 1๊ฐœ ์ด์ƒ ๋“ค์–ด๊ฐ€์•ผํ•˜๋ฉฐ ๊ทธ๋ฃน์˜ ํฌ๊ธฐ๋Š” 2 ์ด์ƒ์ด์–ด์•ผ ํ•œ๋‹ค.

1. ํฌ๊ธฐ๊ฐ€ ๊ฐ€์žฅ ํฐ ๋ธ”๋ก ๊ทธ๋ฃน์„ ์ฐพ๋Š”๋‹ค. ๊ทธ๋Ÿฌํ•œ ๋ธ”๋ก ๊ทธ๋ฃน์ด ์—ฌ๋Ÿฌ ๊ฐœ๋ผ๋ฉด ํฌํ•จ๋œ ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์˜ ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋งŽ์€ ๋ธ”๋ก ๊ทธ๋ฃน, ๊ทธ๋Ÿฌํ•œ ๋ธ”๋ก๋„ ์—ฌ๋Ÿฌ๊ฐœ๋ผ๋ฉด ๊ธฐ์ค€ ๋ธ”๋ก์˜ ํ–‰์ด ๊ฐ€์žฅ ํฐ ๊ฒƒ์„, ๊ทธ ๊ฒƒ๋„ ์—ฌ๋Ÿฌ๊ฐœ์ด๋ฉด ์—ด์ด ๊ฐ€์žฅ ํฐ ๊ฒƒ์„ ์ฐพ๋Š”๋‹ค.
2. 1์—์„œ ์ฐพ์€ ๋ธ”๋ก ๊ทธ๋ฃน์˜ ๋ชจ๋“  ๋ธ”๋ก์„ ์ œ๊ฑฐํ•œ๋‹ค. ๋ธ”๋ก ๊ทธ๋ฃน์— ํฌํ•จ๋œ ๋ธ”๋ก์˜ ์ˆ˜๋ฅผ B๋ผ๊ณ  ํ–ˆ์„ ๋•Œ, B2์ ์„ ํš๋“ํ•œ๋‹ค.
3. ๊ฒฉ์ž์— ์ค‘๋ ฅ์ด ์ž‘์šฉํ•œ๋‹ค.
4. ๊ฒฉ์ž๊ฐ€ 90๋„ ๋ฐ˜์‹œ๊ณ„ ๋ฐฉํ–ฅ์œผ๋กœ ํšŒ์ „ํ•œ๋‹ค.
5. ๋‹ค์‹œ ๊ฒฉ์ž์— ์ค‘๋ ฅ์ด ์ž‘์šฉํ•œ๋‹ค.

์ ์ˆ˜ํš๋“ ๊ณผ์ •์€ ์œ„์™€ ๊ฐ™๋‹ค.

๋จผ์ € ์ €์žฅํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•  ์ •๋ณด๋“ค์ด ๋ญ๊ฐ€ ์žˆ๋Š”์ง€ ์ƒ๊ฐํ•ด๋ณด์ž.

1. ํ˜„์žฌ ๊ฒฉ์žํŒ์˜ ์ƒํ™ฉ์„ ์ €์žฅํ•ด์•ผํ•œ๋‹ค.

A[20][20] ์˜ ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์„œ ์ €์žฅํ•ด๋‘์—ˆ๋‹ค.

2. ๋ธ”๋ก ๊ทธ๋ฃน์„ ํƒ์ƒ‰ํ•  ๋•Œ ํ•ด๋‹น ์นธ์˜ ๋ธ”๋ก์ด ์ด๋ฏธ ์–ด๋–ค ๋ธ”๋ก๊ทธ๋ฃน์— ํฌํ•จ๋˜์–ด ์žˆ๋Š”์ง€๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด

visited[20][20] ๋ฐฐ์—ด์„ ๋งŒ๋“ค์–ด์„œ ์†Œ์† ๋ธ”๋ก๊ทธ๋ฃน์ด ์žˆ๋Š”์ง€๋ฅผ ์ฒดํฌํ–ˆ๋‹ค.

์ด๋•Œ ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์€ ๋ชจ๋“  ๊ทธ๋ฃน์— ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํƒ์ƒ‰ ์ „ ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์˜ visited๋Š” ํ•ญ์ƒ false ์—ฌ์•ผํ•œ๋‹ค.

์ธ์ ‘ํ•œ ๋ธ”๋ก๋ผ๋ฆฌ ์„œ๋กœ ์ด๋™ํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค๋Š” ์กฐ๊ฑด์ด ์žˆ์œผ๋ฏ€๋กœ BFS๋ฅผ ์ด์šฉํ•ด์„œ ํƒ์ƒ‰ํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ธ์ ‘ํ•œ ๋ธ”๋ก์ด ๊ฐ™์€ ์ƒ‰์ด๊ฑฐ๋‚˜ ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์ด๋ฉด ๊ฐ™์€ ๊ทธ๋ฃน์˜ ๋ธ”๋ก์ด๋ผ ํŒ๋‹จํ–ˆ๋‹ค.

3. ๋ธ”๋ก ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ๋ฒกํ„ฐ

ํƒ์ƒ‰ ํ›„ ์—ฌ๋Ÿฌ ๋ธ”๋ก ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•ด์•ผ ์–ด๋–ค ๋ธ”๋ก ๊ทธ๋ฃน์ด ๊ฐ€์žฅ ํฐ์ง€, ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์ด ๋ช‡๊ฐœ๋‚˜ ํฌํ•จ๋˜์—ˆ๋Š”์ง€๋ฅผ ํŒ๋‹จ ํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ณผ์ • 1๋ฒˆ์— ๋ณด๋ฉด

1. ํฌ๊ธฐ๊ฐ€ ๊ฐ€์žฅ ํฐ ๋ธ”๋ก ๊ทธ๋ฃน์„ ์ฐพ๋Š”๋‹ค.
๊ทธ๋Ÿฌํ•œ ๋ธ”๋ก ๊ทธ๋ฃน์ด ์—ฌ๋Ÿฌ ๊ฐœ๋ผ๋ฉด ํฌํ•จ๋œ ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์˜ ์ˆ˜๊ฐ€ ๊ฐ€์žฅ ๋งŽ์€ ๋ธ”๋ก ๊ทธ๋ฃน,
๊ทธ๋Ÿฌํ•œ ๋ธ”๋ก๋„ ์—ฌ๋Ÿฌ๊ฐœ๋ผ๋ฉด ๊ธฐ์ค€ ๋ธ”๋ก์˜ ํ–‰์ด ๊ฐ€์žฅ ํฐ ๊ฒƒ์„, 
๊ทธ ๊ฒƒ๋„ ์—ฌ๋Ÿฌ๊ฐœ์ด๋ฉด ์—ด์ด ๊ฐ€์žฅ ํฐ ๊ฒƒ์„ ์ฐพ๋Š”๋‹ค.โ€‹

๋ผ๊ณ  ๋˜์–ด์žˆ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ๋ธ”๋ก ๊ทธ๋ฃน์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์ €์žฅํ•  ๋•Œ ๋ธ”๋ก ๊ทธ๋ฃน์˜ ํฌ๊ธฐ, ํฌํ•จ๋œ ๋ฌด์ง€๊ฐœ ๋ธ”๋ก์˜ ์ˆ˜, ๊ธฐ์ค€ ๋ธ”๋ก์˜ ์ขŒํ‘œ

๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ์–ด์•ผ ์ง€์›Œ์•ผํ•  ๋ธ”๋ก ๊ทธ๋ฃน์„ ์„ ์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

vector<pair<pair<int,int>,pair<int,int>>> ๋กœ ๋ฒกํ„ฐ๋ฅผ ๋งŒ๋“ค์–ด์„œ ์ด ์„ธ๊ฐ€์ง€ ์ •๋ณด๋ฅผ ์ €์žฅํ–ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  vector๋ฅผ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ๋‹ค๋ฉด ์œ„์˜ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋ธ”๋ก๊ทธ๋ฃน์ด  0๋ฒˆ ์ธ๋ฑ์Šค์— ์˜ฌ ๊ฒƒ์ด๋‹ค.

0๋ฒˆ ์ธ๋ฑ์Šค์— ์žˆ๋Š” ๋ธ”๋ก๊ทธ๋ฃน์˜ ๊ธฐ์ค€ ๋ธ”๋ก์˜ ์ขŒํ‘œ๋ฅผ ์ด์šฉํ•ด์„œ ํ•ด๋‹น ๊ทธ๋ฃน์˜ ๋ธ”๋ก๋“ค์„ ๋ชจ๋‘ ์ง€์šด๋‹ค.

๋‚˜๋Š” ๋ธ”๋ก ์ƒ‰์ด -2์ด๋ฉด ์—†๋Š” ๋ธ”๋ก์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <stack>
#include <vector>
#include <math.h>
#include <queue>
#include <climits>
#include <deque>
#include <algorithm>
#include <iomanip>
#include <map>
#define mod 998244353
using namespace std;
typedef long long ll;
typedef priority_queue<pair<intint>vector<pair<intint>>, greater<pair<intint>>> Priority_queue;
const int INF = INT_MAX;
const int MAX_N = 20 + 5;
int N, M;
int dx[] = {-1,0,1,0};
int dy[] = {0,1,0,-1};
int A[MAX_N][MAX_N];
bool visited[MAX_N][MAX_N];
int Score;
vector<pair<pair<intint>pair<intint>>> Block_Group;
void Find_Group(pair<int,int>);
bool is_ok(pair<intint> now);
void Erase_Group();
void Gravity();
void Rotate();
 
int main(void) {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> N >> M;
 
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            cin >> A[i][j];
        }
    }
    while (true) {
        memset(visited, falsesizeof(visited));
        for (int i = 1; i <= N; i++) {
            for (int j = 1; j <= N; j++) {
                if (!visited[i][j] && A[i][j] > 0) {
                    Find_Group({ i,j });
                }
            }
        }
        if (Block_Group.empty())
            break;
        sort(Block_Group.begin(), Block_Group.end(), greater<pair<pair<intint>pair<intint>>>());
        if (Block_Group[0].first.first < 2)
            break;
        Erase_Group();
        Gravity();
        Rotate();
        Gravity();
    }
    cout << Score << "\n";
    return 0;
}
 
void Find_Group(pair<intint> st) {
    queue<pair<intint>> q;
    q.push(st);
    int Color = A[st.first][st.second];
    pair<intint> Criterion = st;
    int cnt_B = 0;
    vector<pair<intint>> Rainbow;
    while (!q.empty()) {
        pair<intint> now = q.front();
        q.pop();
        if (visited[now.first][now.second])
            continue;
        visited[now.first][now.second] = true;
        cnt_B++;
        if (A[now.first][now.second] != 0) {
            if (Criterion.first > now.first)
                Criterion = now;
            else if (Criterion.first == now.first)
                Criterion.second = min(Criterion.second, now.second);
        }
        else Rainbow.push_back(now);
        for (int i = 0; i < 4; i++) {
            pair<intint> next = { now.first + dy[i], now.second + dx[i] };
            int next_color = A[next.first][next.second];
            if (is_ok(next))
                if (Color == next_color || next_color == 0)
                    q.push(next);
        }
    }
    Block_Group.push_back({ {cnt_B, Rainbow.size()},Criterion});
    for (int i = 0; i < Rainbow.size(); i++)
        visited[Rainbow[i].first][Rainbow[i].second] = false;
    Rainbow.clear();
}
 
void Erase_Group() {
    memset(visited, falsesizeof(visited));
    pair<intint> st = Block_Group[0].second;
    queue<pair<intint>> q;
    q.push(st);
    int color = A[st.first][st.second];
    while (!q.empty()) {
        pair<intint> now = q.front();
        q.pop();
        if (visited[now.first][now.second])
            continue;
        visited[now.first][now.second] = true;
        A[now.first][now.second] = -2;
        for (int i = 0; i < 4; i++) {
            pair<intint> next = { now.first + dy[i], now.second + dx[i] };
            int next_color = A[next.first][next.second];
            if (next_color < 0)
                continue;
            if (is_ok(next)) {
                if (color == next_color || next_color == 0)
                    q.push(next);
            }
        }
    }
    Score += (int)pow(Block_Group[0].first.first, 2);
    Block_Group.clear();
}
 
bool is_ok(pair<intint> now) {
    if (now.first < 1 || now.first > N || now.second < 1 || now.second > N)
        return false;
    return true;
}
 
void Gravity() {
    for (int i = 1; i <= N; i++) {
        for (int j = N; j >= 1; j--) {
            if (A[j][i] < 0)
                continue;
            pair<intint> to = { j, i};
            while (true) {
                pair<intint> next = { to.first + 1, to.second };
                if (is_ok(next) && A[next.first][next.second] == -2)
                    to = next;
                else break;
            }
            if (to.first == j && to.second == i)
                continue;
            A[to.first][to.second] = A[j][i];
            A[j][i] = -2;
        }
    }
}
 
void Rotate() {
    int temp[MAX_N][MAX_N];
    for (int i = 1; i <= N; i++)
        for (int j = 1; j <= N; j++)
            temp[i][j] = A[i][j];
 
    for (int i = 1; i <= N; i++) {
        for (int j = 1; j <= N; j++) {
            A[N + 1 - j][i] = temp[i][j];
        }
    }
}
cs

728x90