백준 - 20061 모노미노도미노2
알고리즘/백준

백준 - 20061 모노미노도미노2

www.acmicpc.net/problem/20061

 

20061번: 모노미노도미노 2

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

www.acmicpc.net

1. 유형

구현

 

2. 풀이

 

이번 문제는 구현할 함수가 많습니다.

  • 입력
  • 맨 밑으로 박스를 내리기
  • 1줄 꽉찬 라인이 있는지
  • 1줄 삭제하고 밑으로 1줄 내리기
  • 연한색 부분에 박스 있는지 확인
  • 남아있는 네모칸 갯수 파악

 

처음에 어려웠던 부분은 blue부분을 어떻게 구현해줄까 하는 부분 입니다.

생각한 결과 blue부분을 따로 구현할 필요가 없습니다. green부분을 대칭 시켜주면 됩니다.

 

아래 그림은 2 3 0이 들어왔을 때 입니다.

blue부분을 바꿔서 생각해 보면 3 0 3으로 바꿔서 생각해 볼 수 있습니다.

즉, t가 가로 형태면 세로로 바꿔주고, xy값을 바꿔주면 됩니다.

이러면 따로 blue부분을 구현해줄 필요가 없습니다.

 

이 부분만 해결하면 나머지는 그냥 노가다로 구현하시면 됩니다.

 

3. 디버깅

 

blue부분 xy대칭 생각

1줄 찼는지 확인하는 함수에서 0번부터 탐색해야 하는데 맨 끝부터 탐색했습니다.

이 부분에서 오류를 찾느라 시간이 걸렸습니다.

 

4. 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static StringTokenizer st;
	static int N, green[][], blue[][], blue_cnt, green_cnt, score;

	static void input() throws IOException {
		st = new StringTokenizer(in.readLine());
		N = Integer.valueOf(st.nextToken());
		int r, c, t;
		green = new int[7][4];
		blue = new int[7][4];
		blue_cnt = 0;
		green_cnt = 0;
		score = 0;
		// 끝줄은 1로 초기화
		for (int j = 0; j < 4; j++) {
			green[6][j] = 1;
			blue[6][j] = 1;
		}
		for (int i = 0; i < N; i++) {
			st = new StringTokenizer(in.readLine());
			t = Integer.valueOf(st.nextToken());
			r = Integer.valueOf(st.nextToken());
			c = Integer.valueOf(st.nextToken());
			green(t, r, c);
			blue(t, r, c);
			// 한줄 꽉 찬거 확인
			line_check(green);
			line_check(blue);
			// 0 1 인덱스 라인 존재여부 확인
			line_top_check(green);
			line_top_check(blue);
		}
	}

	static void green(int t, int r, int c) {
		down(green, t, c);
	}

	static void blue(int t, int r, int c) {
		if (t == 2)
			down(blue, 3, r);
		else if (t == 3)
			down(blue, 2, r);
		else
			down(blue, t, r);
	}

	static void down(int map[][], int t, int c) {
		if (t == 1) {
			for (int i = 1; i + 1 < 7; i++) {
				if (map[i + 1][c] == 1) {
					map[i][c] = 1;
					break;
				}
			}
		} else if (t == 2) {
			for (int i = 1; i + 1 < 7; i++) {
				if (map[i + 1][c] == 1 || map[i + 1][c + 1] == 1) {
					map[i][c] = 1;
					map[i][c + 1] = 1;
					break;
				}
			}
		} else if (t == 3) {
			for (int i = 0; i + 2 < 7; i++) {
				if (map[i + 2][c] == 1) {
					map[i][c] = 1;
					map[i + 1][c] = 1;
					break;
				}
			}
		}
	}

	static void line_check(int map[][]) {
		for (int i = 0; i<6; i++) {
			int cnt = 0;
			for (int j = 0; j < 4; j++) {
				if (map[i][j] == 1)
					cnt++;
				else
					break;
			}
			if (cnt == 4) {
				delete_line(map, i);
				score++;
			}
		}
	}

	static void delete_line(int map[][], int line_num) {
		for (int i = line_num; i - 1 >= 0; i--) {
			for (int j = 0; j < 4; j++) {
				map[i][j] = map[i-1][j];
			}
		}
		for(int j=0; j<4; j++) {
			map[0][j]= 0;
		}
	}

	static void line_top_check(int map[][]) {
		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < 4; j++) {
				if (map[1][j] == 1) {
					delete_line(map, 5);
					break;
				}
			}
		}
	}

	static void count_box() {
		for (int i = 2; i < 6; i++) {
			for (int j = 0; j < 4; j++) {
				if (green[i][j] == 1)
					green_cnt++;
				if (blue[i][j] == 1)
					blue_cnt++;
			}
		}
	}

	public static void main(String[] args) throws IOException {
		input();
		count_box();
		System.out.println(score);
		System.out.println(blue_cnt+green_cnt);
	}
}

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

백준 - 19591 독특한 계산기  (0) 2021.03.10
백준 - 16137 견우와 직녀  (0) 2021.03.07
백준 - 2528 사다리(Java)  (0) 2021.03.02
백준 - 1360 되돌리기(Java)  (0) 2021.02.28
백준 - 3055 탈출(Java)  (0) 2021.02.25