알고리즘/BOJ

[BJ]20061 모노미노도미노2

  • -

 

 

20061번: 모노미노도미노 2 (acmicpc.net)

* 일단 문제를 정독 하고 1시간 이상 반드시 고민이 필요합니다.

 

1시간 이상 고민 했지만 아이디어가 떠오르지 않는다면 동영상에서 약간의 힌트를 얻어봅시다.

 

동영상 설명을 보고도 전혀 구현이 안된다면 연습 부족입니다.
소스를 보고 작성해 본 후 스스로 백지 상태에서 3번 작성해 볼 의지가 있다면 소스를 살짝 보세요.

꼭 작성할 각오가 되어있습니다.
package bj.gold.l2; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.StringReader; import java.util.Arrays; import java.util.StringTokenizer; /** * * @author 은서파 * @since 2022/01/30 * @see https://www.acmicpc.net/problem/20061 * @performance 17256 156 * @category #구현 */ public class BJ_G2_20061_모노미노도미노2 { private static StringBuilder output = new StringBuilder(); private static int N; private static Board boardGreen, boardBlue; public static void main(String[] args) throws IOException { BufferedReader input = new BufferedReader(new InputStreamReader(System.in)); input = new BufferedReader(new StringReader(src)); StringTokenizer tokens; N = Integer.parseInt(input.readLine()); boardGreen = new Board(); boardBlue = new Board(); for (int n = 0; n < N; n++) { tokens = new StringTokenizer(input.readLine()); int t = Integer.parseInt(tokens.nextToken()); int r = Integer.parseInt(tokens.nextToken()); int c = Integer.parseInt(tokens.nextToken()); if (t == 1) { boardGreen.setTile(1, c); boardBlue.setTile(1, r); // 입력 받은 row가 blue에서는 col } else if (t == 2) { boardGreen.setTile(2, c); boardBlue.setTile(3, r); } else { boardGreen.setTile(3, c); boardBlue.setTile(2, r); } } // 정답 출력 output.append(boardGreen.score + boardBlue.score).append("\n").append(boardGreen.getTileCnt() + boardBlue.getTileCnt()); System.out.println(output); } static class Board { int[][] tiles; int score; public Board() { // 맨 아래는 더미행으로 언제나 타일이 있을 것, 맨 오른쪽 컬럼은 해당 row에 있는 tile의 개수 tiles = new int[7][5]; // 맨 마지막 더미행은 타일로 채워주기 Arrays.fill(tiles[6], 1); } private void setTile(int type, int c) { // 타일을 놓을 수 있는 위치에 놓아본다. // 위에서 부터 아래로 타일이 떨어진다. --> 배치 가능한지 확인 // 맨 위의 두 칸은 언제나 비어있다.!! for (int r = 2; r < tiles.length; r++) { int[] check = tiles[r]; if (type == 1 && check[c] == 1) { tiles[r - 1][c] = 1; tiles[r - 1][4]++; break; } else if (type == 2 && (check[c] == 1 || check[c + 1] == 1)) { tiles[r - 1][c] = 1; tiles[r - 1][c + 1] = 1; tiles[r - 1][4] += 2; break; } else if (type == 3 && check[c] == 1) { tiles[r - 1][c] = 1; tiles[r - 1][4] += 1; tiles[r - 2][c] = 1; tiles[r - 2][4] += 1; break; } } // 삭제할 행을 처리한다. checkRow(); } private void checkRow() { // 1. 진한 색깔 영역 처리 - 4번 컬럼값을 기준으로 그 위의 행들을 한칸씩 아래로 이동, score 증가, 맨 위는 새로운 row 삽입 for (int r = 5; r >= 2; r--) { if (tiles[r][4] == 4) { for (int r2 = r; r2 >= 1; r2--) { tiles[r2] = tiles[r2 - 1]; } tiles[0] = new int[] { 0, 0, 0, 0, 0 }; score++; // 다시 현재 row를 검사해야 하니까.. r++; } } // 2. 희미한 색깔 영역 처리 for (int r = 1; r >= 0; r--) { if (tiles[1][4] != 0) { for (int r2 = 5; r2 >= 1; r2--) { tiles[r2] = tiles[r2 - 1]; } tiles[0] = new int[] { 0, 0, 0, 0, 0 }; } } } public int getTileCnt() { int cnt = 0; for (int r = 2; r < tiles.length - 1; r++) { cnt += tiles[r][4]; } return cnt; } } // REMOVE_START public static String src = "8\r\n" + "1 1 1\r\n" + "2 3 0\r\n" + "3 2 2\r\n" + "3 2 3\r\n" + "3 1 3\r\n" + "2 0 0\r\n" + "3 2 0\r\n" + "3 1 2"; // REMOVE_END }

 

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.