백준 11559 puyo puyo
본문 바로가기
알고리즘 모음집/알고리즘 (Algorithm)

백준 11559 puyo puyo

by KyeongMin 2019. 9. 8.
728x90
반응형

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

 

11559번: Puyo Puyo

현재 주어진 상황에서 몇연쇄가 되는지 출력하라. (하나도 터지지 않는다면 0을 출력하면 된다.)

www.acmicpc.net

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include<stdio.h>
#include<queue>
using namespace std;
char board[13][7];
char color[6= { 'R','G','B','P','Y' };
int chk[12][7];
int earse[20];
char cboard[13= { '.', };// 터지고나서 공간 정리하기 위한 배열
int dy[] = { 0,1,0,-1, };
int dx[] = { 1,0,-1,0 };
void init()
{
    for (int i = 0; i < 12; i++)
    {
        cboard[i] = '.';
    }
    for (int i = 0; i < 12; i++)
    {
        for (int j = 0; j < 6; j++)
        {
            chk[i][j] = 0;
        }
    }
}
typedef struct D {
    int y, x, cnt;
}D;
int main(void)
{
    int ret = 0;
 
    ///
 
    for (int i = 0; i < 12; i++)
    {
        scanf("%s", board[i]);// 입력
    }
    while (1)
    {
        int flag = 0;
        int idx = 0;
        int cnt = 0;
        for (int c = 0; c < 6; c++)// 색깔 별로 돌리기 위함
        {
            queue <D>q;
            for (int i = 0; i < 12; i++)
            {
                for (int j = 0; j < 6; j++)
                {
                    if (board[i][j] == color[c] && chk[i][j] == 0)
                    {
                        int c1 = 1;
                        cnt++;
                        chk[i][j] = cnt;
                        q.push({ i,j,cnt });
                        while (!q.empty())
                        {
                            D d = q.front(); q.pop();
                            for (int k = 0; k < 3; k++)
                            {
                                D n;
                                n.y = d.y + dy[k];
                                n.x = d.x + dx[k];
                                n.cnt = d.cnt;
                                if (0 <= n.y && n.y < 12 && 0 <= n.x && n.x < 6)
                                {
                                    if (board[n.y][n.x] == color[c] && chk[n.y][n.x] == 0)
                                    {
                                        c1++;
                                        chk[n.y][n.x] = cnt;
                                        q.push(n);
                                    }
                                }
                            }
                        }
                        //printf("%d %d\n", cnt, c1);
                        if (c1 >= 4) {
                            earse[idx++= cnt;
                        }
                    }
                }
            }
        }
 
        for (int e = 0; e < idx; e++)// 4개 이상 삭제
        {
            flag = 1;
            for (int i = 0; i < 12; i++)
            {
                for (int j = 0; j < 6; j++)
                {
                    if (chk[i][j] == earse[e]) board[i][j] = '.';
                }
            }
        }
 
        for (int x = 0; x < 6; x++)
        {
            idx = 11;
            init();
            for (int y = 11; y >= 0; y--)
            {
                if (board[y][x] != '.') {
                    cboard[idx--= board[y][x];
                    board[y][x] = '.';
                }
            }
            for (int y = 11; y >= 0; y--)
            {
                board[y][x] = cboard[y];
            }
        }
 
        /*for (int i = 0; i < 12; i++)
        {
        for (int j = 0; j < 6; j++)
        {
        printf("%2c", board[i][j]);
        }
        printf("\n");
        }*/
        if (flag == 1)
            ret++;
        else
        {
            printf("%d\n", ret);
            return 0;
        }
        flag = 0;
        for (int i = 0; i < 20; i++)
        {
            earse[i] = 0;
        }
    }
    return 0;
}
 
 
 
 

 

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
#include<stdio.h>
#include<string.h>
#include<queue>
#define NSIZE 12
#define MSIZE 6
using namespace std;
char input[NSIZE][MSIZE];
int dy[] = { 0,1,0,-1 };
int dx[] = { 1,0,-1,0 };
int chk[NSIZE][MSIZE];
int num[75];
int cnt1 = 0;
void dfs(int y, int x, int cnt, char color) {
    for (int dir = 0; dir < 4; dir++) {
        int ny = y + dy[dir];
        int nx = x + dx[dir];
        if (0 <= ny && ny < NSIZE && 0 <= nx && nx < MSIZE) {
            if (chk[ny][nx] == 0 && input[ny][nx] == color) {
                chk[ny][nx] = cnt;
                cnt1++;
                dfs(ny, nx, cnt, color);
            }
        }
    }
}
int ret = 0;
int main(void) {
    for (int i = 0; i < 12; i++) {
        scanf("%s", input[i]);
    }
    while (1) {
        memset(num, 0sizeof(num));
        memset(chk, 0sizeof(chk));
        int cnt = 0;
        for (int i = 0; i < 12; i++) {
            for (int j = 0; j < 6; j++) {
                if (input[i][j] != '.' && chk[i][j] == 0) {
                    cnt1 = 0;
                    ++cnt;
                    chk[i][j] == cnt;
                    dfs(i, j, cnt, input[i][j]);
                    num[cnt] = cnt1;
                }
            }
        }
        int c = 0;
        for (int k = 0; k < 75; k++) {
            if (num[k] >= 4) {
                c++;
                for (int i = 0; i < 12; i++) {
                    for (int j = 0; j < 6; j++) {
                        if (chk[i][j] == k) input[i][j] = '.';
                    }
                }
            }
        }
        if (c == 0)break;
        if (c != 0)ret++;
        queue<char> q;
        for (int j = 0; j < 6; j++) {
            for (int i = 11; i >= 0; i--) {
                if (input[i][j] != '.') {
                    q.push(input[i][j]);
                    input[i][j] = '.';
                }
            }
            int idx = 11;
            while (!q.empty()) {
                input[idx--][j] = q.front(); q.pop();
            }
        }
 
    }
    printf("%d", ret);
    return 0;
}
 
 





이전에 풀었던 문제였지만 예전에 너무 대충 구현했던것 같아서 초심의 마음으로 다시 구현 했습니다
위에 소스는 최근에 구현한 소스이고
제일 처음에 있는 소스는 예전에 구현한 소스 입니다
예전에는 단순히 R G B P Y 에 대해서 나눠서 구현을 했다면 이번에는 한번에 구현을 했는데
간단히 설명 드리자면 0, 0부터 ' . '이 아닌것에
대해서 탐색을 하다 만나면 거기서부터 dfs깊이 탐색을 하여 각 블록을 나눕니다 그리고 거기에서 4개 이상이 데는 블록의 번호를 알기위해 따로 배열을 두어 저장하고

탐색이 끝나고 블록의 갯수가 적힌 배열을 이용해 반복문을 돌려 그 숫자인 블록을 . 으로 바꾸고 제거로 인해 떠있는 블록을 내리고 돌아가는 식으로 구현 했습니다

자세한 것은 소스를 보시면 이해가 되실꺼에요
오늘은 이런식으로 소스가 바뀜을 보시면 좋다고 생각합니다
내일도 오늘도 즐거운 코딩!!!

 

728x90
반응형

'알고리즘 모음집 > 알고리즘 (Algorithm)' 카테고리의 다른 글

백준 3055 탈출  (0) 2019.09.09
백준 16985 Maaaaaaaaaze  (0) 2019.09.09
백준 16197 두 동전  (0) 2019.09.08
조합의 모든것 풀어봅시다  (0) 2019.08.20
순열의 모든것 풀어봅시다  (0) 2019.08.20

댓글