Study/Coding Test

[백준] 모노미노도미노2

_gayeon 2021. 10. 19. 21:02

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

 

20061번: 모노미노도미노 2

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

www.acmicpc.net

 

지우고 위에있던 타일을 밑으로 내려야한다는걸 까먹음.

#define _CRT_SECURE_NO_DEPRECATE

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cstring>
#include <deque>

using namespace std;

int N;
int point, answer;
vector<vector<int>> blocks; //{t,x,y}

int board[10][10];

void init() {
	for (int i = 0; i < 10; i++) {
		memset(board[i], 0, sizeof(board[i]));
	}

	blocks = {};
	point = 0;
	answer = 0;
}

void input() {
	cin >> N;
	for (int i = 0; i < N; i++) {
		int t, x, y;
		cin >> t >> x >> y;
		blocks.push_back({ t,x,y });
	}
}

void initSpecial() {
	for (int i = 4; i <= 5; i++) {
		for (int j = 0; j <= 3; j++) {
			board[i][j] = 0;
			board[j][i] = 0;
		}
	}
}

void print() {
	for (int i = 0; i < 10; i++) {
		for (int j = 0; j < 10; j++) {
			cout << board[i][j] << " ";
		}
		cout << endl;
	}
	cout << endl;
}


void remove() {
	//초록색에서 행 제거
	vector<int> v; //남길 행.
	int green = 0; //지우는 행 개수
	for (int r = 9; r >= 4; r--) {
		bool isTarget = true;
		for (int c = 0; c <= 3; c++) {
			if (board[r][c] == 0) {
				isTarget = false;
				v.push_back(r);
				break;
			}
		}
		if (isTarget) {  //제거할 행이라면
			point++;
			green++;
		}
	}

	if (v.size() > 0) {
		int idx = 9;
		for (int i = 0; i < v.size(); i++) {
			for (int j = 0; j <= 3; j++) {
				board[idx][j] = board[v[i]][j];
			}
			idx--;
		}
	}
	for (int i = 4; i < 4 + green; i++) {
		for (int c = 0; c <= 3; c++) {
			board[i][c] = 0;
		}
	}
	
	//파란색에서 행 제거
	v.clear(); //남길 열 리셋
	int blue = 0;
	for (int c = 9; c>= 4; c--) {
		bool isTarget = true;
		for (int r = 0; r <= 3; r++) {
			if (board[r][c] == 0) {
				isTarget = false;
				v.push_back(c);
				break;
			}
		}
		if (isTarget) {  //제거할 행이라면
			point++;
			blue++;
		}
	}

	if (v.size() > 0) {
		int idx = 9;
		for (int i = 0; i < v.size(); i++) {
			for (int j = 0; j <= 3; j++) {
				board[j][idx] = board[j][v[i]];
			}
			idx--;
		}
	}

	for (int i = 4; i < 4 + blue; i++) {
		for (int r = 0; r <= 3; r++) {
			board[r][i] = 0;
		}
	}
}

void checkSpecial() {
	//초록색 체크
	int green = 0;
	for (int r = 4; r <= 5; r++) {
		for (int c = 0; c <= 3; c++) {
			if (board[r][c] == 1) {
				green++;
				break;
			}
		}
	}

	if (green > 0) { //지워야하는 경우
		for (int r = 9 - green; r >= 4; r--) {
			for (int c = 0; c <= 3; c++) {
				board[r + green][c] = board[r][c];
			}
		}
	}
	
	//파란색 체크
	int blue = 0;
	for (int c = 4; c <= 5; c++) {
		for (int r = 0; r <= 3; r++) {
			if (board[r][c] == 1) {
				blue++;
				break;
			}
		}
	}

	if (blue > 0) { //지워야하는 경우
		for (int c = 9 - blue; c >= 4; c--) {
			for (int r = 0; r <= 3; r++) {
				board[r][c + blue] = board[r][c];
			}
		}
	}

	initSpecial();
}

void moveBlock(int type, int row, int col) {
	if (type == 1) { // ㅁ
		//초록색 이동
		int r = 3; //시작
		while (r <= 9 && board[r][col] == 0) { //비어있으면 
			r++;
		}
		board[r-1][col] = 1;

		//파란색이동
		int c = 3;
		while (c <= 9 && board[row][c] == 0) {
			c++;
		}
		board[row][c-1] = 1;
	}
	else if (type == 2) { //ㅁㅁ
		//초록색 이동
		int r = 3; //시작
		while (r <=9 && board[r][col] == 0 && board[r][col+1] == 0) { //비어있으면 
			r++;
		}
		board[r-1][col] = 1;
		board[r-1][col+1] = 1;

		//파란색이동
		int c = 3;
		while (c <= 8 && board[row][c] == 0 && board[row][c+1] == 0) {
			c++;
		}
		board[row][c-1] = 1;
		board[row][c] = 1;
	}
	else {
		//초록색 이동
		int r = 3; //시작
		while (r <= 8 && board[r][col] == 0 && board[r+1][col] == 0) { //비어있으면 
			r++;
		}
		board[r-1][col] = 1;
		board[r][col] = 1;

		//파란색이동
		int c = 3;
		while (c <= 9 && board[row][c] == 0 && board[row+1][c] == 0) {
			c++;
		}
		board[row][c-1] = 1;
		board[row+1][c-1] = 1;
	}

	//print();
}

void solve() {
	for (int i = 0; i < N; i++) {
		int type = blocks[i][0];
		int row = blocks[i][1];
		int col = blocks[i][2];

		moveBlock(type, row, col);
		remove();
		checkSpecial();

		//print();
	}

	//초록색 타일 개수
	for (int r = 4; r <= 9; r++) {
		for (int c = 0; c <= 3; c++) {
			if (board[r][c] == 1) {
				answer++;
			}
			if (board[c][r] == 1) {
				answer++;
			}
		}
	}
}

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

	//freopen("input.txt", "r", stdin);

	init();
	input();
	solve();

	cout << point << endl;
	cout << answer << endl;

	return 0;
}