[백준/BOJ] 백준 20061번 : 모노미노도미노 2

2021. 3. 14. 18:59알고리즘 문제풀이

www.acmicpc.net/problem/20061

 

20061번: 모노미노도미노 2

모노미노도미노는 아래와 같이 생긴 보드에서 진행되는 게임이다. 보드는 빨간색 보드, 파란색 보드, 초록색 보드가 그림과 같이 붙어있는 형태이다. 게임에서 사용하는 좌표 (x, y)에서 x는 행,

www.acmicpc.net

더 이상 움직이면 범위를 넘을 때나 더 이상 움직이면 다른 블록이랑 만날 때까지 블록을 이동시키고, 블록이 사라지는 경우를 확인하여 사라진 윗부분 블록을 이동시켰다. 블록을 이동시킬 때는 deque를 이용했다.

 

코드

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

int n;
int dxdy[4][2] = { {0,0},{0,0},{0,1},{1,0} };
int score = 0;
int cnt = 0;
vector<vector<int>> board(10, vector<int>(10, 0));

void Delete()
{
	//초록색 행이 꽉 찬것 확인
	for (int i = 9; i >= 4; i--)
	{
		bool check = true;
		for (int j = 0; j < 4; j++)
		{
			if (board[i][j] == 0)
			{
				check = false;
				break;
			}
		}

		//i행이 블록으로 가득 차있을때
		if (check == true)
		{
			for (int j = 0; j < 4; j++)
				board[i][j] = 0; //해당 행을 다 지운다
			score++;

			for (int j = 0; j < 4; j++)
			{
				deque<int> temp;
				for (int k = i - 1; k >= 4; k--)
				{
					temp.push_back(board[k][j]);
					board[k][j] = 0;
				}

				int temp_size = temp.size();
				for (int k = i; k > i - temp_size; k--)
				{
					board[k][j] = temp.front();
					temp.pop_front();
				}
			}
			i++; //다시 i행부터 확인해야 하므로(블록들을 내렸으므로)
		}
	}

	int soft_green = 0;
	//초록색 연한부분 확인
	for (int i = 4; i <= 5; i++)
	{
		bool check = false;
		for (int j = 0; j < 4; j++)
		{
			if (board[i][j] != 0)
			{
				check = true;
				break;
			}
		}

		if (check == true)
			soft_green++;
	}

	for (int j = 0; j < 4; j++)
	{
		deque<int> temp;
		for (int i = 9 - soft_green; i >= 4; i--)
		{
			temp.push_back(board[i][j]);
			board[i][j] = 0;
		}

		int temp_size = temp.size();
		for (int i = 9; i > 9 - temp_size; i--)
		{
			board[i][j] = temp.front();
			temp.pop_front();
		}
	}

	//파란색 열이 가득 찬것 확인
	for (int j = 9; j >= 4; j--)
	{
		bool check = true;
		for (int i = 0; i < 4; i++)
		{
			if (board[i][j] == 0)
			{
				check = false;
				break;
			}
		}

		//j열이 블록으로 가득 차있을때
		if (check == true)
		{
			for (int i = 0; i < 4; i++)
				board[i][j] = 0; //해당 열을 다 지운다
			score++;

			for (int i = 0; i < 4; i++)
			{
				deque<int> temp;
				for (int k = j - 1; k >= 4; k--)
				{
					temp.push_back(board[i][k]);
					board[i][k] = 0;
				}

				int temp_size = temp.size();
				for (int k = j; k > j - temp_size; k--)
				{
					board[i][k] = temp.front();
					temp.pop_front();
				}
			}
			j++; //다시 j열부터 확인해야 하므로(블록들을 내렸으므로)
		}
	}

	int soft_blue = 0;
	//파란색 연한부분 확인
	for (int j = 4; j <= 5; j++)
	{
		bool check = false;
		for (int i = 0; i < 4; i++)
		{
			if (board[i][j] != 0)
			{
				check = true;
				break;
			}
		}

		if (check == true)
			soft_blue++;
	}

	for (int i = 0; i < 4; i++)
	{
		deque<int> temp;
		for (int j = 9 - soft_blue; j >= 4; j--)
		{
			temp.push_back(board[i][j]);
			board[i][j] = 0;
		}

		int temp_size = temp.size();
		for (int j = 9; j > 9 - temp_size; j--)
		{
			board[i][j] = temp.front();
			temp.pop_front();
		}
	}

}

void Move(int t, int x, int y)
{
	pair<int, int> block1 = make_pair(x, y);
	pair<int, int> block2 = make_pair(x + dxdy[t][0], y + dxdy[t][1]);

	//초록색으로 움직이기
	while (1)
	{
		//더이상 움직이면 범위를 넘을때
		if (block1.first + 1 >= 10 || block2.first + 1 >= 10)
		{
			board[block1.first][block1.second] = 1;
			board[block2.first][block2.second] = 1;

			break;
		}

		//더이상 움직이면 다른 블록이랑 만날때
		if (board[block1.first + 1][block1.second] != 0 || board[block2.first + 1][block2.second] != 0)
		{
			board[block1.first][block1.second] = 1;
			board[block2.first][block2.second] = 1;

			break;
		}

		block1.first++;
		block2.first++;
	}

	block1 = make_pair(x, y);
	block2 = make_pair(x + dxdy[t][0], y + dxdy[t][1]);
	//파란색으로 움직이기
	while (1)
	{
		//더이상 움직이면 범위를 넘을때
		if (block1.second + 1 >= 10 || block2.second + 1 >= 10)
		{
			board[block1.first][block1.second] = 1;
			board[block2.first][block2.second] = 1;

			break;
		}

		//더이상 움직이면 다른 블록이랑 만날때
		if (board[block1.first][block1.second + 1] != 0 || board[block2.first][block2.second + 1] != 0)
		{
			board[block1.first][block1.second] = 1;
			board[block2.first][block2.second] = 1;

			break;
		}

		block1.second++;
		block2.second++;
	}
}

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

	cin >> n;

	for (int i = 0; i < n; i++)
	{
		int t, x, y;

		cin >> t >> x >> y;

		Move(t, x, y);
		Delete();
	}

	for (int i = 4; i < 10; i++)
		for (int j = 0; j < 4; j++)
			if (board[i][j] != 0)
				cnt++;

	for (int j = 4; j < 10; j++)
		for (int i = 0; i < 4; i++)
			if (board[i][j] != 0)
				cnt++;

	cout << score << "\n";
	cout << cnt;

	return 0;
}