알고리즘 공부/구현 , 시뮬레이션

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

kdhoooon 2021. 10. 20. 19:00

문제


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

 

20061번: 모노미노도미노 2

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

www.acmicpc.net

 

문제가 너무 길어서 링크로 대체한다.

 

 

 

풀이


우선 blue, green 일 때 두가지 경우로 나눠서 풀어야한다.(행과 열의 개수가 다르고 방향이 다르기 때문에)

 

한가지로 구현 하고 나머지는 행과 열을 바꾸면 된다.

 

<블록을 놓는 코드>

static void fallGreen(int t, int x, int y){
		
		boolean isBottom = false;
		int index = 0;
		while(!isBottom) {
			for(int i = 0 ; i < shape[t].length ; i++) {
				int nx = shape[t][i][0] + index;
				int ny = y + shape[t][i][1];
				
				if(nx >= 6 || green[nx][ny] != 0) {
					isBottom = true;
					index--;
					break;
				}
			}
			
			if(!isBottom) {
				index++;
			}else { 
				for(int i = 0 ; i < shape[t].length ; i++) {
					int nx = shape[t][i][0] + index;
					int ny = y + shape[t][i][1];
					green[nx][ny] = 1;
				}
			}			
		}
	}

블록을 놓을 때 green 의 경우는 red와 열을 공유하기 때문에,

행을 늘리면서 해당 위치에 블록이 있거나 밖으로 벗어날 때의 index 를 찾아서, 그에 맞는 값을 넣어주면 된다.

 

 

<지우는 코드>

static void deleteGreen() {
	
	for(int i = 0 ; i < 6 ; i++) {			
		boolean isPossible = true;
		for(int j = 0 ; j < 4 ; j++) {
			if(green[i][j] == 0) {
				isPossible = false;
				break;
			}
		}
		
		if(isPossible) {
			for(int j = i ; j >= 0 ; j--) {
				if(j != 0) {
					for(int k = 0 ; k < 4 ; k++) {
						green[j][k] = green[j-1][k];
					}
				}
				else {
					for(int k = 0 ; k < 4 ; k++) {
						green[j][k] = 0;
					}
				}
			}
			score++;
		}
	}
}

한개의 행에 모든 수가 1 이면,

해당 줄 부터 위에있는 줄은 한줄씩 밑으로 값을 복사하고 마지막 줄을 0 으로 만들어 주면 된다.

이 때, score++ 을 하여 점수를 올려준다.

 

<0 , 1 번 줄에 블록이 있는 지 찾는 코드>

static void specialGreen() {
	
	int cnt = 0;
	for(int i = 0 ; i < 2 ; i++) {
		for(int j = 0 ; j < 4 ; j++) {
			if(green[i][j] != 0) {
				cnt++;
				break;
			}
		}
	}
	
	if(cnt != 0) {
		for(int i = 5 ; i >= cnt ; i--) {
			for(int j = 0 ; j < 4 ; j++) {
				green[i][j] = green[i - cnt][j];
				green[i - cnt][j] = 0;
			}
		}
	}
}

0 ~ 1 줄에 블록이 하나라도 있으면 cnt++ 을 하여 그만큼의 줄을 당겨서 복사한다.

이때는 나머지 두줄을 0 으로 만들어주기위해 미리미리 값을 복사한뒤에 해당 위치는 0으로 만들어 줬다.

 

 

이렇게 한뒤에 열과 행을 바꿔 blue 를 구현하면 된다.

 

<전체코드>

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

public class Main {
	
	static int[][] green, blue;
	static int[][][] shape = { {{0,0}}, {{0,0},{0,1}}, {{0,0},{1,0}} };
	static int N;
	static int score;
	
	public static void main(String[] args) throws NumberFormatException, IOException{	
		
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

		green = new int[6][4];
		blue = new int[4][6];
		
		N = Integer.parseInt(br.readLine());
		score = 0;
		for(int i = 0 ; i < N ; i++) {
			StringTokenizer st = new StringTokenizer(br.readLine());
			
			int t = Integer.parseInt(st.nextToken()) - 1;
			int x = Integer.parseInt(st.nextToken());
			int y = Integer.parseInt(st.nextToken());
			
			fallGreen(t, x, y);
			fallBlue(t, x, y);
			
			deleteGreen();
			deleteBlue();
			
			specialGreen();
			specialBlue();
		}
		
		bw.write(score + "\n" + getCount());
		bw.flush();
		bw.close();
		br.close();
	}
	
	static int getCount() {
		
		int sum = 0;
		for(int i = 0 ; i < 6 ; i++) {
			for(int j = 0 ; j < 4 ; j++) {
				if(green[i][j] != 0) {
					sum++;
				}
				
				if(blue[j][i] != 0) {
					sum++;
				}
			}
		}
		
		return sum;
	}
	
	static void print() {
		
		System.out.println("BLUE : ");
		for(int i = 0 ; i < 4 ; i++) {
			for(int j = 0 ; j < 6 ; j++) {
				System.out.print(blue[i][j] + " ");
			}
			System.out.println();
		}
		
		System.out.println("GREEN : ");
		for(int i = 0 ; i < 6 ; i++) {
			for(int j = 0 ; j < 4 ; j++) {
				System.out.print(green[i][j] + " ");
			}
			System.out.println();
		}
	}
	
	static void specialGreen() {
		
		int cnt = 0;
		for(int i = 0 ; i < 2 ; i++) {
			for(int j = 0 ; j < 4 ; j++) {
				if(green[i][j] != 0) {
					cnt++;
					break;
				}
			}
		}
		
		if(cnt != 0) {
			for(int i = 5 ; i >= cnt ; i--) {
				for(int j = 0 ; j < 4 ; j++) {
					green[i][j] = green[i - cnt][j];
					green[i - cnt][j] = 0;
				}
			}
		}
	}
	
	static void specialBlue() {
		
		int cnt = 0;
		for(int i = 0 ; i < 2 ; i++) {
			for(int j = 0 ; j < 4 ; j++) {
				if(blue[j][i] != 0) {
					cnt++;
					break;
				}
			}
		}
		
		if( cnt != 0) {
			for(int i = 5 ; i >= cnt ; i--) {
				for(int j = 0 ; j < 4 ; j++) {
					blue[j][i] = blue[j][i - cnt];
					blue[j][i - cnt] = 0;
				}
			}
		}
	}
	
	static void deleteGreen() {
		
		for(int i = 0 ; i < 6 ; i++) {			
			boolean isPossible = true;
			for(int j = 0 ; j < 4 ; j++) {
				if(green[i][j] == 0) {
					isPossible = false;
					break;
				}
			}
			
			if(isPossible) {
				for(int j = i ; j >= 0 ; j--) {
					if(j != 0) {
						for(int k = 0 ; k < 4 ; k++) {
							green[j][k] = green[j-1][k];
						}
					}
					else {
						for(int k = 0 ; k < 4 ; k++) {
							green[j][k] = 0;
						}
					}
				}
				score++;
			}
		}
	}
	
	static void deleteBlue() {
		
		for(int i = 0 ; i < 6 ; i++) {			
			boolean isPossible = true;
			for(int j = 0 ; j < 4 ; j++) {
				if(blue[j][i] == 0) {
					isPossible = false;
					break;
				}
			}
			
			if(isPossible) {
				for(int j = i ; j >= 0 ; j--) {
					if(j != 0) {
						for(int k = 0 ; k < 4 ; k++) {
							blue[k][j] = blue[k][j - 1];
						}
					}
					else {
						for(int k = 0 ; k < 4 ; k++) {
							blue[k][j] = 0;
						}
					}
				}
				score++;
			}
		}
	}
	
	static void fallGreen(int t, int x, int y){
		
		boolean isBottom = false;
		int index = 0;
		while(!isBottom) {
			for(int i = 0 ; i < shape[t].length ; i++) {
				int nx = shape[t][i][0] + index;
				int ny = y + shape[t][i][1];
				
				if(nx >= 6 || green[nx][ny] != 0) {
					isBottom = true;
					index--;
					break;
				}
			}
			
			if(!isBottom) {
				index++;
			}else { 
				for(int i = 0 ; i < shape[t].length ; i++) {
					int nx = shape[t][i][0] + index;
					int ny = y + shape[t][i][1];
					green[nx][ny] = 1;
				}
			}			
		}
	}
	
	static void fallBlue(int t, int x, int y) {
		boolean isBottom = false;
		int index = 0;
	
		while(!isBottom) {
			for(int i = 0 ; i < shape[t].length ; i++) {
				int nx =  x + shape[t][i][0];
				int ny = shape[t][i][1] + index;
				
				if(ny >= 6 || blue[nx][ny] != 0) {
					isBottom = true;
					index--;
					break;
				}
			}
			
			if(!isBottom) {
				index++;
			}else { 
				for(int i = 0 ; i < shape[t].length ; i++) {
					int nx = x + shape[t][i][0];
					int ny = shape[t][i][1] + index;					
					blue[nx][ny] = 1;
				}
			}			
		}
	}
}