알고리즘/[문제풀이] BOJ

[BOJ] 17822 - 원판 돌리기

be-lgreen 2021. 10. 21. 23:09

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

 

17822번: 원판 돌리기

반지름이 1, 2, ..., N인 원판이 크기가 작아지는 순으로 바닥에 놓여있고, 원판의 중심은 모두 같다. 원판의 반지름이 i이면, 그 원판을 i번째 원판이라고 한다. 각각의 원판에는 M개의 정수가 적혀

www.acmicpc.net

 

난이도

구현 / 난이도 ⭐️⭐️ / 1시간30분 소요

 

주의할 점

크기 어렵지 않으나, 실수한  부분이 많아서 오래걸렸다.

이런 문제의 경우 단계단계 구현결과를 확인하는게  좋은 것 같다. 

 

 

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

int N, M, T; // n: 원판 갯수 m: 원판 위 숫자 갯수 T : 원판 돌리기 케이스
int arr[51][51] = {0};

void rotate(int x, int d, int k)
{
    int c_arr[51] = {0};
    for (int i = 0; i < M; i++)
    {
        c_arr[i] = arr[x][i];
    }

    int new_index;
    if (d == 0)
    { // 시계방향
        // 1 2 3 4 5
        // 4 5 1 2 3
        for (int i = 0; i < M; i++)
        {
            new_index = i + k;
            if (new_index > M - 1) // check point1) 부등호 조심
                new_index -= M;
            arr[x][new_index] = c_arr[i];
        }
    }
    else if (d == 1)
    {
        // 1 2 3 4 5
        // 3 4 5 1 2
        for (int i = 0; i < M; i++)
        {
            new_index = i - k;
            if (new_index < 0)
                new_index += M;
            arr[x][new_index] = c_arr[i];
        }
    }
}

void remove_number()
{
    set<pair<int, int> > ss;
    // 세로로 확인
    for (int i = 0; i < M; i++)
    {
        int pre_num = arr[1][i];
        for (int j = 2; j <= N; j++)
        {
            if (arr[j][i] != pre_num)
            {
                pre_num = arr[j][i];
            }
            else if (arr[j][i] == pre_num)
            {
                if (arr[j][i] == 0)
                    continue;
                ss.insert(make_pair(j - 1, i));
                ss.insert(make_pair(j, i));
            }
        }
    }

    // 가로로  확인
    for (int i = 1; i <= N; i++)
    {
        int pre_num = arr[i][M - 1];
        for (int j = 0; j < M; j++)
        {
            if (arr[i][j] != pre_num)
            {
                pre_num = arr[i][j];
            }
            else if (arr[i][j] == pre_num)
            {
                if (arr[i][j] == 0)
                    continue;
                ss.insert(make_pair(i, j));
                if (j == 0)
                {
                    ss.insert(make_pair(i, M - 1));
                }
                else
                {
                    ss.insert(make_pair(i, j - 1));
                }
            }
        }
    }

    if (!ss.empty())
    {
        set<pair<int, int> >::iterator iter;
        int x, y;
        for (iter = ss.begin(); iter != ss.end(); iter++)
        {
            x = iter->first;
            y = iter->second;

            arr[x][y] = 0;
        }
    }
    else
    {
        int total = 0;
        int total_cnt = 0;
        float avg = 0;
        for (int i = 1; i <= N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                if (arr[i][j] == 0)
                    continue;
                total += arr[i][j];
                total_cnt += 1;
            }
        }
        avg = (float)total / (float)total_cnt; // check pont2) 22/6일 경우 float으로 계산해야지 3.xxx라는 수가 나오는데, 3은 3.xxx보다  작다.

        for (int i = 1; i <= N; i++)
        {
            for (int j = 0; j < M; j++)
            {
                if (arr[i][j] == 0)
                    continue;

                if ((float)arr[i][j] > avg)
                {
                    arr[i][j] -= 1;
                }
                else if (float(arr[i][j]) < avg)
                {
                    arr[i][j] += 1;
                }
            }
        }
    }
}

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

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

    int X, D, K;
    for (int i = 0; i < T; i++)
    {
        scanf("%d %d %d", &X, &D, &K);
        for (int j = X; j <= N; j += X)
        {
            // X의 배수 원판을 D방향을 K만큼 돌린다.
            rotate(j, D, K);
        }
        remove_number();
    }

    int result = 0;
    for (int i = 1; i <= N; i++)
    {
        for (int j = 0; j < M; j++)
        {
            if (arr[i][j] != 0)
            {
                result += arr[i][j];
            }
        }
    }
    printf("%d", result);
}