티스토리 뷰

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

 

20058번: 마법사 상어와 파이어스톰

마법사 상어는 파이어볼과 토네이도를 조합해 파이어스톰을 시전할 수 있다. 오늘은 파이어스톰을 크기가 2N × 2N인 격자로 나누어진 얼음판에서 연습하려고 한다. 위치 (r, c)는 격자의 r행 c

www.acmicpc.net

 

난이도

1번: 구현(배열 회전) + DFS / 난이도⭐️⭐️⭐️/ 못품

2번: 구현(배열 회전) + DFS/ 난이도⭐️ / 1시간

 

주의할 점

처음 풀었을때는 배열을 슬라이스해서 90도 회전하는 부분이 가장 어렵게 느껴졌다.

두번째 풀었을때는 배열 회전하는 부분이 쉽게 풀려서 나머지 부분은 쉽게 풀었다.

 

함수를  분리하는게 가장 중요하다.

#include <stdio.h>
#include <vector>
#include <cmath>
#include <utility>
#include <queue>
using namespace std;

int board[65][65] = {0};
int N, Q, M;
int dirx[4] = {0, 1, 0, -1};
int diry[4] = {1, 0, -1, 0};
/*
00 01 02 03
10 11 12 13
20 21 22 23
30 31 32 33

30 20 10 00
31 21 11 01
32 22 12 02
33 23 13 03
*/
void rotate(int x, int y, int slice)
{
    vector<vector<int> > c_board(slice, vector<int>(slice, 0));
    for (int i = 0; i < slice; i++)
    {
        for (int j = 0; j < slice; j++)
        {
            c_board[j][slice - 1 - i] = board[i + x][j + y];
        }
    }

    for (int i = 0; i < slice; i++)
    {
        for (int j = 0; j < slice; j++)
        {
            board[i + x][j + y] = c_board[i][j];
        }
    }
}

void firestorm(int slice)
{
    for (int i = 0; i < M; i += slice)
    {
        for (int j = 0; j < M; j += slice)
        {
            rotate(i, j, slice);
        }
    }
}

void reduce_ice()
{
    vector<pair<int, int> > v;

    int newx, newy;
    int ice_cnt;
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (board[i][j] <= 0)
                continue;

            ice_cnt = 0;
            for (int k = 0; k < 4; k++)
            {
                newx = i + dirx[k];
                newy = j + diry[k];

                if (newx < 0 || newy < 0 || newx > M - 1 || newy > M - 1)
                    continue;

                if (board[newx][newy] > 0)
                {
                    ice_cnt += 1;
                }
            }

            if (ice_cnt < 3)
            {
                v.push_back(make_pair(i, j));
            }
        }
    }

    for (int i = 0; i < v.size(); i++)
    {
        board[v[i].first][v[i].second] -= 1;
    }
}

int main()
{
    scanf("%d %d", &N, &Q);

    M = pow(2, N);
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < M; j++)
        {
            scanf("%d", &board[i][j]);
        }
    }

    int L;
    for (int i = 0; i < Q; i++)
    {
        scanf("%d", &L);
        firestorm(pow(2, L));
        reduce_ice();
    }

    int total_ice = 0;
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (board[i][j] < 0)
            {
                printf("debug\n");
            }

            total_ice += board[i][j];
        }
    }
    printf("%d\n", total_ice);

    bool check[65][65] = {false};
    queue<pair<int, int> > q;
    int max_ice_group = 0;
    int ice_cnt = 0;
    int x, y, newx, newy;
    for (int i = 0; i < M; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (board[i][j] == 0)
                continue;

            if (check[i][j])
                continue;

            q.push(make_pair(i, j));
            check[i][j] = true;
            ice_cnt = 1;
            while (!q.empty())
            {
                x = q.front().first;
                y = q.front().second;
                q.pop();

                for (int k = 0; k < 4; k++)
                {
                    newx = x + dirx[k];
                    newy = y + diry[k];

                    if (newx < 0 || newy < 0 || newx > M - 1 || newy > M - 1)
                        continue;

                    if (board[newx][newy] == 0)
                        continue;

                    if (board[newx][newy] > 0 && check[newx][newy] == false) // check_point1) ||로 해둬서 틀렸다. 실수.
                    {
                        q.push(make_pair(newx, newy));
                        check[newx][newy] = true;
                        ice_cnt += 1;
                    }
                }
            }

            if (ice_cnt > max_ice_group)
                max_ice_group = ice_cnt;
        }
    }

    printf("%d", max_ice_group);
}

'알고리즘 > [문제풀이] BOJ' 카테고리의 다른 글

[BOJ] 20061 - 모노미노도미노 2  (0) 2021.10.22
[BOJ] 17142 - 연구소 3  (0) 2021.10.22
[BOJ] 17822 - 원판 돌리기  (0) 2021.10.21
[BOJ] 19236 - 청소년 상어  (0) 2021.10.21
[BOJ] 29237 - 어른 상어  (0) 2021.10.20
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/05   »
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
글 보관함