<Baekjoon> #20061 Simulation,구현_모노미노도미노2 c++

Google 아니고 Joogle·2022년 3월 29일
0

SAMSUNG SW Test

목록 보기
26/39
post-thumbnail

#20061 모노미노도미노2
문제 제목만큼이나 까다로운 문제였다. 특히 좌표를 다루는 게..

Solution

  • 함수는 크게 T 모양에 따라 blue, green 칸으로 이동하는 함수 moveBlock(t,y,x), Blue칸에 있는 블록이 합쳐지는 mergeBlue(), Green칸에 있는 블록이 합쳐지는 mergeGreen()이 있다
  • 먼저 찐한 칸에 있는 블록을 조사해 한 행이나 열이 가득 차 있으면 그 칸을 없애고 나머지 칸들이 합치고 연한칸을 조사해 보았을 때 블록이 있다면 끝의 칸부터 없애고 합친다

🎲1. Move Block

  • 1*1 t1모양
    Blue: 바로 오른쪽에 블록이 있을 때까지 이동한 후 해당 위치에 블록을 놓는다
    Green: 바로 아래쪽에 블록이 있을 때까지 이동한 후 해당 위치에 블록을 놓는다
	if (t == 1) {
		//move to blue
		int nx = x;
		while (nx < mapSize - 1 && !map[y][nx + 1])
			nx++;
		map[y][nx] = 1;
		//move to green
		int ny = y;
		while (ny < mapSize - 1 && !map[ny + 1][x])
			ny++;
		map[ny][x] = 1;
	}
  • 1*2 t2모양
    Blue: 바로 오른쪽에 블록이 있을 때까지 이동한 후 해당 위치를 기준으로 왼쪽 가로로 2칸을 차지하게 블록을 놓는다
    Green: 처음 블록을 놓는 칸이 (y,x) (y,x+1) 인 경우 바로 아래 가로로 연속하는 두 칸 중 하나라도 블록이 있을 경우까지 이동하고 (ny, x) (ny, x+1)위치에 블록을 놓는다
	//1*2 block
	else if (t == 2) {
		//move to blue
		int nx = x + 1;
		while (nx < mapSize - 1 && !map[y][nx + 1])
			nx++;
		map[y][nx] = 1; map[y][nx - 1] = 1;
		//move to green 
		int ny = y + 1;
		while (ny < mapSize - 1 && !map[ny + 1][x] && !map[ny + 1][x + 1])
			ny++;
		map[ny][x] = 1; map[ny][x + 1] = 1;
	}
  • 2*1 t3모양
    Blue: 처음 블록을 놓는 칸이 (y,x) (y+1,x)인 경우 바로 옆에 세로로 연속하는 두 칸 중 하나라도 블록이 있을 경우까지 이동하고 (y,nx) (y+1, nx)위치에 블록을 놓는다
    Green: 바로 아래에 블록이 있을 때까지 이동한 후 해당 위치를 기준으로 위로 2칸을 차지하게 블록을 놓는다
	//2*1 block
	else if (t == 3) {
		//move to blue 
		int nx = x + 1;
		while (nx < mapSize - 1 && !map[y][nx + 1] && !map[y + 1][nx + 1])
			nx++;
		map[y][nx] = 1; map[y + 1][nx] = 1;
		//move to green
		int ny = y + 1;
		while (ny < mapSize - 1 && !map[ny + 1][x])
			ny++;
		map[ny][x] = 1; map[ny - 1][x] = 1;
	}

🎲2. Merge Blue/Green

(blue칸만을 본다)

  • 찐한 칸만을 살펴 보았을 때, 한 열이 블록으로 가득 차 있을 때 그 갯수를 remove에 저장
  • start에는 가득차 있는 열 중에 가장 큰 열의 번호가 저장되어 있다
	//count number of merging cols
	for (int x = 6; x < mapSize; x++) {
		for (int y = 0; y <= 3; y++) {
			if (map[y][x] == 0) break;
			if (y == 3) {
				start = x;
				remove++;
			}
		}
	}
  • 가득차 있는 가장 큰 열부터 앞에서 remove칸씩 땡겨와 저장
	//merge from 4 to 9 clos
	if (start > -1) {
		for (int x = start - remove; x >= 4; x--) {
			for (int y = 0; y <= 3; y++) {
				map[y][x + remove] = map[y][x];
				map[y][x] = 0;
			}
		}
	}
  • 투명한 두 개의 4,5번 열 중에 블록이 하나라도 있는 열의 갯수를 저장한다
	int cols = 0;
	for (int x = 4; x <= 5; x++) {
		for (int y = 0; y <= 3; y++) {
			if (map[y][x] == 1) {
				cols++; break;
			}
		}
	}
  • 열의 갯수만큼 제일 끝에서부터 땡겨와 저장하고 4,5,번 열은 비워준다
	if (cols > 0) {
		for (int x = 9 - cols; x >= 4; x--) {
			for (int y = 0; y <= 3; y++) {
				map[y][x + cols] = map[y][x];
			}
		}
		for (int x = 4; x <= 5; x++)
			for (int y = 0; y <= 3; y++)
				map[y][x] = 0;
	}

Sorce Code

#include <iostream>

using namespace std;
const int mapSize = 10;

int map[mapSize][mapSize];
int score = 0;

void mergeBlue() {
	int start = -1;
	int remove = 0;
	//count number of merging cols
	for (int x = 6; x < mapSize; x++) {
		for (int y = 0; y <= 3; y++) {
			if (map[y][x] == 0) break;
			if (y == 3) {
				start = x;
				remove++;
			}
		}
	}
	score += remove;
	//merge from 4 to 9 clos
	if (start > -1) {
		for (int x = start - remove; x >= 4; x--) {
			for (int y = 0; y <= 3; y++) {
				map[y][x + remove] = map[y][x];
				map[y][x] = 0;
			}
		}
	}

	//print();

	//check 4-5 cols
	int cols = 0;
	for (int x = 4; x <= 5; x++) {
		for (int y = 0; y <= 3; y++) {
			if (map[y][x] == 1) {
				cols++; break;
			}
		}
	}
	//merge from 4 to 9 cols
	if (cols > 0) {
		for (int x = 9 - cols; x >= 4; x--) {
			for (int y = 0; y <= 3; y++) {
				map[y][x + cols] = map[y][x];
			}
		}
		for (int x = 4; x <= 5; x++)
			for (int y = 0; y <= 3; y++)
				map[y][x] = 0;
	}
	//print();
}

void mergeGreen() {
	int start = -1;
	int remove = 0;
	//count number of merging rows
	for (int y = 6; y < mapSize; y++) {
		for (int x = 0; x <= 3; x++) {
			if (map[y][x] == 0) break;
			if (x == 3) {
				start = y;
				remove++;
			}
		}
	}
	score += remove;
	//merge from 4 to 9 rows
	if (start > -1) {
		for (int y = start - remove; y >= 4; y--) {
			for (int x = 0; x <= 3; x++) {
				map[y+remove][x] = map[y][x];
				map[y][x] = 0;
			}
		}
	}
	//check 4-5 rows
	int rows = 0;
	for (int y = 4; y <= 5; y++) {
		for (int x = 0; x <= 3; x++) {
			if (map[y][x] == 1) {
				rows++; break;
			}
		}
	}
	//merge from 4 to 9 rows
	if (rows > 0) {
		for (int y = 9 - rows; y >= 4; y--) {
			for (int x = 0; x <= 3; x++) {
				map[y+rows][x] = map[y][x];
			}
		}
		for (int y = 4; y <= 5; y++)
			for (int x = 0; x <= 3; x++)
				map[y][x] = 0;
	}

	//print();
}

void moveBlock(int t, int y, int x) {
	//1*1 block
	if (t == 1) {
		//move to blue
		int nx = x;
		while (nx < mapSize - 1 && !map[y][nx + 1])
			nx++;
		map[y][nx] = 1;
		//move to green
		int ny = y;
		while (ny < mapSize - 1 && !map[ny + 1][x])
			ny++;
		map[ny][x] = 1;
	}
	//1*2 block
	else if (t == 2) {
		//move to blue
		int nx = x + 1;
		while (nx < mapSize - 1 && !map[y][nx + 1])
			nx++;
		map[y][nx] = 1; map[y][nx - 1] = 1;
		//move to green 
		int ny = y + 1;
		while (ny < mapSize - 1 && !map[ny + 1][x] && !map[ny + 1][x + 1])
			ny++;
		map[ny][x] = 1; map[ny][x + 1] = 1;
	}
	//2*1 block
	else if (t == 3) {
		//move to blue 
		int nx = x + 1;
		while (nx < mapSize - 1 && !map[y][nx + 1] && !map[y + 1][nx + 1])
			nx++;
		map[y][nx] = 1; map[y + 1][nx] = 1;
		//move to green
		int ny = y + 1;
		while (ny < mapSize - 1 && !map[ny + 1][x])
			ny++;
		map[ny][x] = 1; map[ny - 1][x] = 1;
	}
}

void input() {
	int N;
	cin >> N;
	for (int i = 0; i < N; i++) {
		int t, y, x;
		cin >> t >> y >> x;
		moveBlock(t, y, x);
		mergeBlue();
		mergeGreen();
	}
}

int countBlock() {
	int cnt = 0;
	for (int y = 0; y <= 3; y++)
		for (int x = 4; x < mapSize; x++)
			cnt += map[y][x];
	for (int y = 4; y < mapSize; y++)
		for (int x = 0; x <= 3; x++)
			cnt += map[y][x];
	return cnt;
}

int main() {
	input();
	cout << score << endl;
	cout << countBlock() << endl;
	return 0;
}

profile
Backend 개발자 지망생

0개의 댓글