[백준/BOJ] 백준 17822번 : 원판 돌리기

2021. 2. 9. 00:10알고리즘 문제풀이

www.acmicpc.net/problem/17822

 

17822번: 원판 돌리기

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

www.acmicpc.net

Rotate(int x, int d, int k) 로 x의 배수 원판을 d방향으로 k칸 회전을 하는 작업을 한뒤 회전한뒤 처리할 작업(Erase()를 통해)을한다.

 

코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>
using namespace std;

int n, m, t;
vector<vector<int>> board(51, vector<int>(51));

void Erase()
{
	vector<pair<int, int>> erase_num;
	for (int i = 1; i <= n; i++)
	{
		if (board[i][1] == board[i][2] && board[i][1] != 0)
		{
			erase_num.push_back(make_pair(i, 1));
			erase_num.push_back(make_pair(i, 2));
		}
		if (board[i][1] == board[i][m] && board[i][1] != 0)
		{
			erase_num.push_back(make_pair(i, 1));
			erase_num.push_back(make_pair(i, m));
		}
		if (board[i][m] == board[i][m - 1] && board[i][m] != 0)
		{
			erase_num.push_back(make_pair(i, m));
			erase_num.push_back(make_pair(i, m - 1));
		}
		if (board[i][m] == board[i][1] && board[i][m] != 0)
		{
			erase_num.push_back(make_pair(i, m));
			erase_num.push_back(make_pair(i, 1));
		}
		for (int j = 2; j <= m - 1; j++)
		{
			if (board[i][j] == board[i][j - 1] && board[i][j] != 0)
			{
				erase_num.push_back(make_pair(i, j));
				erase_num.push_back(make_pair(i, j - 1));
			}
			if (board[i][j] == board[i][j + 1] && board[i][j] != 0)
			{
				erase_num.push_back(make_pair(i, j));
				erase_num.push_back(make_pair(i, j + 1));
			}
		}
	}
	for (int j = 1; j <= m; j++)
	{
		if (board[1][j] == board[2][j] && board[1][j] != 0)
		{
			erase_num.push_back(make_pair(1, j));
			erase_num.push_back(make_pair(2, j));
		}

		if (board[n][j] == board[n - 1][j] && board[n][j] != 0)
		{
			erase_num.push_back(make_pair(n, j));
			erase_num.push_back(make_pair(n - 1, j));
		}

		for (int i = 2; i <= n - 1; i++)
		{
			if (board[i][j] == board[i - 1][j] && board[i][j] != 0)
			{
				erase_num.push_back(make_pair(i, j));
				erase_num.push_back(make_pair(i - 1, j));
			}

			if (board[i][j] == board[i + 1][j] && board[i][j] != 0)
			{
				erase_num.push_back(make_pair(i, j));
				erase_num.push_back(make_pair(i + 1, j));
			}
		}
	}

	for (int i = 0; i < erase_num.size(); i++)
		board[erase_num[i].first][erase_num[i].second] = 0;

	if (erase_num.size() == 0)
	{
		double avg;
		int sum = 0;
		int cnt = 0;

		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
			{
				if (board[i][j] != 0)
				{
					sum += board[i][j];
					cnt++;
				}
			}

		avg = (double)sum / cnt;

		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= m; j++)
			{
				if (board[i][j] != 0)
				{
					if (board[i][j] > avg)
						board[i][j]--;

					else if (board[i][j] < avg)
						board[i][j]++;
				}
			}
	}

}

void Rotate(int x, int d, int k) //x의 배수 원판을 d방향으로 k칸 회전
{

	for (int i = x; i <= n; i = i + x)
	{
		vector<int> temp;
		for (int j = 1; j <= m; j++)
			temp.push_back(board[i][j]);

		if (d == 0)
		{
			for (int j = 0; 1 + k + j <= m; j++)
			{
				board[i][1 + k + j] = temp[j];

				if (1 + k + j == m)
				{
					for (int kk = 0; kk < k; kk++)
						board[i][1 + kk] = temp[j + 1 + kk];
				}
			}
		}

		if (d == 1)
		{
			for (int j = k; j < temp.size(); j++)
			{
				board[i][1 - k + j] = temp[j];

				if (j == temp.size() - 1)
				{
					for (int kk = 0; kk < k; kk++)
						board[i][1 - k + j + 1 + kk] = temp[kk];
				}
			}
		}
	}
	Erase(); //회전한뒤 처리할 작업
}

int Solve()
{
	int ret = 0;

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			ret += board[i][j];

	return ret;
}

int main()
{
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);

	cin >> n >> m >> t;

	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			int input;
			cin >> input;

			board[i][j] = input;
		}

	for (int i = 0; i < t; i++)
	{
		int x, d, k;
		cin >> x >> d >> k;

		Rotate(x, d, k);
	}

	cout << Solve();
}