본문 바로가기
백준 알고리즘/구현

모노미노도미노 2

by paysmile 2021. 3. 8.

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

 

 

20061번: 모노미노도미노 2

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

www.acmicpc.net

#include <iostream>
#include <cstring>

using namespace std;
int n, t, x, y;
int blue[4][6], green[6][4];
int answer = 0;
pair<int, int> b;
pair<int, int> g;

void MoveBlock(int x, int y, int n) {
	int movei = x;
	int movej = 0;

	//파랑칸으로 이동
	while (true) {
		if (movej < 5) {
			if (blue[movei][movej + 1] == 1) {
				blue[movei][movej] = 1;
				break;
			}
		}
		if (movej == 5) {
			blue[movei][movej] = 1;
			break;
		}
		movej += 1;
	}
	b = make_pair(movei, movej);

	movei = 0;
	movej = y;
	//초록칸으로 이동
	while (true) {
		if (movei < 5) {
			if (green[movei + 1][movej] == 1) {
				green[movei][movej] = 1;
				break;
			}
		}
		if (movei == 5) {
			green[movei][movej] = 1;
			break;
		}
		movei += 1;
	}
	g = make_pair(movei, movej);
}

void RemakeMapGreen(int ii) {
	for (int i = ii - 1; i >= 0; i--) {
		for (int j = 0; j <= 3; j++) {
			green[i + 1][j] = green[i][j];
		}
	}
	for (int i = 0; i <= 3; i++)
		green[0][i] = 0;
}

void RemakeMapBlue(int ii) {
	for (int j = ii - 1; j >= 0; j--) {
		for (int i = 0; i <= 3; i++) {
			blue[i][j + 1] = blue[i][j];
		}
	}
	for (int i = 0; i <= 3; i++)
		blue[i][0] = 0;
}

void CheckFill() {
	//파랑칸 체크
	for (int j = 0; j <= 5; j++) {
		int count = 0;
		for (int i = 0; i <= 3; i++) {
			if (blue[i][j] == 1)
				count += 1;
		}
		if (count == 4) {
			answer += 1;
			RemakeMapBlue(j);
		}
	}

	//초록칸 체크
	for (int i = 0; i <= 5; i++) {
		int count = 0;
		for (int j = 0; j <= 3; j++) {
			if (green[i][j] == 1)
				count += 1;
		}
		if (count == 4) {
			answer += 1;
			RemakeMapGreen(i);
		}
	}
}

void RemakeBlue(int ii) {
	//ii==0, 1  //거꾸로 가져오기
	if (ii == 1 || ii==0) {
		for (int j = 4; j >= 0; j--) {
			for (int i = 0; i <= 3; i++) {
				blue[i][j + 1] = blue[i][j];
			}
		}
	}
	//ii==2
	if (ii == 2) {
		for (int j = 3; j >= 0; j--) {
			for (int i = 0; i <= 3; i++) {
				blue[i][j + 2] = blue[i][j];
			}
		}
	}
	for (int i = 0; i <= 3; i++) {
		blue[i][0] = 0;
		blue[i][1] = 0;
	}
}

void RemakeRed(int ii) {
	//ii==0, 1
	if (ii == 1) {
		for (int i = 4; i >= 0; i--) {
			for (int j = 0; j <= 3; j++) {
				green[i + 1][j] = green[i][j];
			}
		}
	}
	//ii==2
	if (ii == 2) {
		for (int i = 3; i >= 0; i--) {
			for (int j = 0; j <= 3; j++) {
				green[i + 2][j] = green[i][j];
			}
		}
	}
	for (int i = 0; i <= 3; i++) {
		green[0][i] = 0;
		green[1][i] = 0;
	}
}

void CheckSmooth() {
	//파랑칸 체크
	int flag = -1;

	for (int j = 0; j <= 1; j++) {
		for (int i = 0; i <= 3; i++) {
			if (blue[i][j] == 1 && j == 0) {
				flag = 0;
				break;
			}
			else if (blue[i][j] == 1 && j == 1) {
				if (flag == -1) {
					flag = 1;
				}
				else if (flag == 0) {
					flag = 2;
				}
			}
		}
	}
	if (flag == 0) {
		RemakeBlue(0);
	}
	else if (flag == 1) {
		RemakeBlue(1);
	}
	else if (flag == 2) {
		RemakeBlue(2);
	}

	flag = -1;
	//초록칸 체크
	for (int i = 0; i <= 1; i++) {
		for (int j = 0; j <= 3; j++) {
			if (green[i][j] == 1 && i == 0) {
				flag = 0;
				break;
			}
			else if (green[i][j] == 1 && i == 1) {
				if (flag == -1) {
					flag = 1;
				}
				else if (flag == 0) {
					flag = 2;
				}
			}
		}
	}
	if (flag == 0) {
		RemakeRed(0);
	}
	else if (flag == 1) {
		RemakeRed(1);
	}
	else if (flag == 2) {
		RemakeRed(2);
	}

}

int NumCount() {
	int count = 0;

	for (int i = 0; i <= 3; i++) {
		for (int j = 0; j <= 5; j++) {
			if (blue[i][j] == 1)
				count += 1;
		}
	}

	for (int i = 0; i <= 5; i++) {
		for (int j = 0; j <= 3; j++) {
			if (green[i][j] == 1)
				count += 1;
		}
	}
	return count;
}

int main(void) {
	cin >> n;
	memset(blue, 0, sizeof(blue));
	memset(green, 0, sizeof(green));

	for (int i = 0; i < n; i++) {
		cin >> t >> x >> y;
		if (t == 1)
			MoveBlock(x, y, 0);
		else if (t == 2) {
			MoveBlock(x, y + 1, 1);
			pair<int, int> temp = g;
			MoveBlock(x, y, 2);
			if (temp.first > g.first) {
				green[temp.first][temp.second] = 0;
				green[g.first][temp.second] = 1;
			}
			else if (temp.first < g.first) {
				green[g.first][g.second] = 0;
				green[temp.first][g.second] = 1;
			}
		}
		else if (t == 3) {
			MoveBlock(x + 1, y, 1);
			pair<int, int> temp = b;
			MoveBlock(x, y, 2);
			if (temp.second > b.second) {
				blue[temp.first][temp.second] = 0;
				blue[temp.first][b.second] = 1;
			}
			else if (temp.second < b.second) {
				blue[b.first][b.second] = 0;
				blue[b.first][temp.second] = 1;
			}
		}
		CheckFill();
		CheckSmooth();
	}
	cout << answer << endl;
	cout << NumCount();
	return 0;
}

'백준 알고리즘 > 구현' 카테고리의 다른 글

새로운 게임 2 C++  (0) 2021.03.19
주사위 윷놀이 C++  (0) 2021.03.10
어른 상어 C++  (0) 2021.03.04
컨베이어 벨트 위의 로봇 C++  (0) 2021.03.01
마법사 상어와 토네이도  (0) 2021.02.22