슈뢰딩거의 고등어

[백준] 20061 모노미노도미노2 본문

알고리즘

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

슈뢰딩거의 고등어 2022. 1. 17. 22:39

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

 

20061번: 모노미노도미노 2

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

www.acmicpc.net

 

붙어있는 블록 gravity 기울이기

파란색 맵이 오른쪽으로 중력이 작용하고 있으므로 시계방향으로 90도 회전해서 고려하도록 한다.

(초록맵처럼 중력을 아래로 적용할 수 있다. 따로 함수를 설정하지 않아도 된다.)

1. blue, green 맵의 상단에 블록을 위치시킨다.

  1) blue 맵의 맨 위에 블록을 위치한다.  (x : blue 맵은 90도 회전한 것이기 때문에, red 맵에 위치한 블록의 y 값이 blue 맵의 x 가 된다.)

  2) green 맵에 맨 위에 블록을 위치한다.  (x : red 에서 그대로 내리면 되기 때문에, red 맵에 위치한 블록의 x 값이 green 맵의 x 가 된다.) 

2. 중력을 작동시킨다.

3. 꽉찬 줄이 있는지 확인한다. 있다면 그 줄을 삭제하고 score 를 +1 한다. 그리고 중력을 가동시킨다. 꽉찬 줄이 없을때까지 반복한다.

4. 0, 1 행에 블록이 존재하는 지 확인한다. 있다면 맨 아래줄 5 행을 삭제하고 중력을 가동시킨다. 0, 1 행에 블록이 존재하지 않을 때까지 반복한다.

1. ~ 4. 를 반복한다.

5. blue, green 맵에 남아있는 블록의 갯수를 count 한다.

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

int red[4][4];
int blue [6][4];
int green [6][4];
int n, t, x, y, score;

void gravity2(int y, int x, int arr[][4]) {

	arr[y][x] = 1;
	//arr[y][x+1] = 1;

	for(int x=0; x<4; x++) {
		bool exits = false;
		for(int y=4; y>=0; y--) {
			// -1, -2 는 이동을 안해도 댐
			if(arr[y][x] != 1)
				continue;

			int move = 0; // 바로 밑칸이랑 비교 움직일수 있다고 가정
			// end || not -

			while(true) {
				move++;
				if(arr[y+move][x] != 0 || arr[y+move][x+1] != 0|| y+move == 6) {
					move--;
					break;
				}
			}

			arr[y+move][x] = 2;
			arr[y+move][x+1] = 2;
			if(move != 0) 
				arr[y][x] = 0;
			
		}

	}

}


void gravity(int arr[][4]) {
	// gravity
	for(int x=0; x<4; x++) {
		bool exits = false;
		for(int y=4; y>=0; y--) {
			// -1, -2 는 이동을 안해도 댐
			if(arr[y][x] != 1)
				continue;

			int move = 0; // 바로 밑칸이랑 비교 움직일수 있다고 가정
			// end || not 

			while(true) {
				move++;
				if(arr[y+move][x] != 0 || y+move == 6) {
					move--;
					break;
				}
			}

			arr[y+move][x] = 2;
			if(move != 0)
				arr[y][x] = 0;
		}

	}
}

void move_down(int arr[][4], int row) {
	for(int y=row-1; y >= 0; y--)
		for(int x=0; x<4; x++) {
			arr[y+1][x] = arr[y][x];
			arr[y][x] = 0;
		}
}

void check_full(int arr[][4]) {

	bool loop = true;

	while(loop) {

		loop = false;
		for(int i=0; i<6; i++) {
			bool full_line = true;
			for(int j=0; j<4; j++)
				if(arr[i][j] == 0)
					full_line = false;
			if(full_line == true)  {
				loop = true;
				break;
			}

		}

		for(int i=5; i>=2; i--) {
			bool full = true;
			for(int j=0; j<4; j++) {
				if(arr[i][j] == 0) {
					full = false;
					break;
				}
			}
			if(full) {
				score++;
				move_down(arr, i);
			}
		}

		for(int i=0; i<2; i++)
			for(int j=0; j<4; j++)
				if(arr[i][j] == 2) {
					move_down(arr, 5);
				}

	}

}

void solve(int t, int y, int x) {
	// green
	if(t == 1) {
		green[0][x] = 1;
		blue[0][y] = 1;
		gravity(green);
		gravity(blue);
	}
	else if(t == 2) {
		blue[0][y] = 1;
		blue[1][y] = 1;
		gravity(blue);
		gravity2(0, x, green);

	}
	else if(t == 3) {
		green[0][x] = 1;
		green[1][x] = 1;
		gravity(green);
		gravity2(0, y, blue);
	}
	
	check_full(green);
	check_full(blue);
	
}

int count() {
	int ret = 0;
	for(int i=0; i<6; i++)
		for(int j=0; j<4; j++)
			if(blue[i][j] != 0)
				ret++;
			
	for(int i=0; i<6; i++)
		for(int j=0; j<4; j++)
			if(green[i][j] != 0)
				ret++;

	return ret;
}

int main() {
	scanf("%d", &n);

	for(int i=0; i<n; i++){
		scanf("%d %d %d", &t, &x, &y);
		solve(t, x, y);
	}

	int res = count();
	printf("%d\n", score);
	printf("%d\n", res);

}

'알고리즘' 카테고리의 다른 글

[백준] 1074 Z 분할정복  (0) 2022.01.19
[백준] 1978 소수 찾기  (0) 2022.01.18
[백준] 23288 주사위 굴리기  (0) 2022.01.17
[백준] 19238 스타트택시  (0) 2022.01.17
[BOJ] 17779 게리맨더링 2 (c++)  (0) 2022.01.13
Comments