[java]모노미노도미노 2 - 백준20061
문제
풀이
문제 해석을 하자면,
- 굉장히 조건 설명을 잘해주고 있으나 굉장히 구현이 긴 문제…
- 블록을 놓은 위치가 순서대로 주어졌을 때, 얻은 점수와 초록색 보드와 파란색 보드에 타일이 있는 칸의 개수를 모두 구해보자.
풀이
- 이 문제의 경우 그림으로 잘 설명을 해주기 때문에 무엇을 구현해야 하는지는 알기 쉽다.
- 다만, 구현할게 많아서 이를 구현하는데 오래걸렸다ㅜㅜ
- 하나씩 알아보자.
- 입력좌표 형태 : (x,y) -> 행,열 -> (0,0) 부터
- 타일종류 : 3가지 -> 타일 최대크기 2
- 배열의 요소에 1로 표시해서 구분하자
- “0~1 인덱스 특별 배열자리” 는 턴 종료마다 항상 비어있게된다. (“삭제, 이동 등등 때문”)
- 따라서 따로 Red 배열 없이 “0~1 인덱스” 자리에 타일 삽입할 것이다.
- 타일종류 3가지 전부 최대크기 2라서 충분히 가능
- 크게 3가지 규칙을 준수해야 한다.
- 삽입할때 규칙 -> insert
- 삭제할때 규칙 -> delete
- 0~1 인덱스쪽 제거할때 규칙 -> zeroOne
- 이때, 이동함수 2개만 구현해서 재사용하자.
- 행이나 열전체 1칸씩 이동 함수 -> moveCol, moveRow
- 타일 종류별(3종류) 배열 끝까지 이동 함수 -> moveBlueTile, moveGreenTile
코드
public static int N;
public static int result;
public static int[][] G = new int[6][6];
public static int[][] B = new int[6][6];
// 타일 이동함수(BLUE)
public static void moveBlueTile(int t, int x, int y) {
if(t==1) {
// (x, y)
int cy = y;
while(true) {
y+=1;
if(y>=6) break;
if(B[x][y]==1) break;
}
y-=1;
B[x][cy] = 0;
B[x][y] = 1;
}else if(t==2) {
// (x, y), (x, y+1)
int cy = y+1;
while(true) {
y+=1;
if(y>=6) break;
if(B[x][y]==1) break;
}
y-=1;
B[x][cy] = 0; B[x][cy-1] = 0;
B[x][y] = 1; B[x][y-1] = 1;
}else {
// (x, y), (x+1, y)
int cy = y;
while(true) {
y+=1;
if(y>=6) break;
if(B[x][y]==1 || B[x+1][y]==1) break;
}
y-=1;
B[x][cy] = 0; B[x+1][cy] = 0;
B[x][y] = 1; B[x+1][y] = 1;
}
}
// 타일 이동함수(GREEN)
public static void moveGreenTile(int t, int x, int y) {
if(t==1) {
// (x, y)
int cx = x;
while(true) {
x+=1;
if(x>=6) break;
if(G[x][y]==1) break;
}
x-=1;
G[cx][y] = 0;
G[x][y] = 1;
}else if(t==2) {
// (x, y), (x, y+1)
int cx = x;
while(true) {
x+=1;
if(x>=6) break;
if(G[x][y]==1 || G[x][y+1]==1) break;
}
x-=1;
G[cx][y] = 0; G[cx][y+1] = 0;
G[x][y] = 1; G[x][y+1] = 1;
}else {
// (x, y), (x+1, y)
int cx = x+1;
while(true) {
x+=1;
if(x>=6) break;
if(G[x][y]==1) break;
}
x-=1;
G[cx][y] = 0; G[cx-1][y] = 0;
G[x][y] = 1; G[x-1][y] = 1;
}
}
// 열단위 1칸 이동함수
public static void moveCol(int ny) {
if(ny+1>=6) return;
for(int i=0;i<4;i++) {
B[i][ny+1] = B[i][ny];
B[i][ny] = 0; // 이동했으니 이전값은 제거
}
}
// 행단위 1칸 이동함수
public static void moveRow(int nx) {
if(nx+1>=6) return;
for(int i=0;i<4;i++) {
G[nx+1][i] = G[nx][i];
G[nx][i] = 0; // 이동했으니 이전값은 제거
}
}
public static void insert(int t, int x, int y) {
int bx = x; int by = y;
int rx = x; int ry = y;
//[0~1 특별배열] 자리로 이동위해 y수정 -> BLUE
if(by==1) by-=1;
else if(by==2) by-=2;
else if(by==3) by-=3;
//[0~1 특별배열] 자리로 이동위해 x수정 -> RED
if(rx==1) rx-=1;
else if(rx==2) rx-=2;
else if(rx==3) rx-=3;
moveBlueTile(t, x, by);
moveGreenTile(t, rx, y);
}
public static void delete() {
// BLUE 삭제 있으면?
int[] blues = new int[6]; // 삭제 인덱스(열) 담는 배열
int idx = 0;
for(int i=0; i<6; i++) {
boolean check = true;
for(int j=0; j<4; j++) {
if(B[j][i]==0) check=false;
}
if(check) blues[idx++]=i;
}
result += idx;
for(int k=0; k<6; k++) {
if(blues[k]==0) break;
for(int i=blues[k]; i>0; i--) { // 삭제 인덱스부터 1칸씩 밀어주기
moveCol(i-1);
}
}
// GREEN 삭제 있으면?
int[] greens = new int[6]; // 삭제 인덱스(행) 담는 배열
idx = 0;
for(int i=0; i<6; i++) {
boolean check = true;
for(int j=0; j<4; j++) {
if(G[i][j]==0) check=false;
}
if(check) greens[idx++]=i;
}
result += idx;
for(int k=0; k<6; k++) {
if(greens[k]==0) break;
for(int i=greens[k]; i>0; i--) { // 삭제 인덱스부터 1칸씩 밀어주기
moveRow(i-1);
}
}
}
public static void zeroOne() {
//BLUE
int count = 0;
for(int j=0; j<2; j++){
for(int i=0; i<4; i++){
if(B[i][j]==1) {
count++; break;
}
}
}
for(int i=0; i<count; i++){
for(int j=5; j>0; j--) { // 끝자리 삭제! 인덱스 1칸씩 밀어주기
moveCol(j-1);
}
}
//Green
count = 0;
for(int i=0; i<2; i++){
for(int j=0; j<4; j++){
if(G[i][j]==1) {
count++; break;
}
}
}
for(int i=0; i<count; i++){
for(int j=5; j>0; j--) { // 끝자리 삭제! 인덱스 1칸씩 밀어주기
moveRow(j-1);
}
}
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
N = Integer.parseInt(br.readLine());
for(int i=0; i<N; i++) {
//input
StringTokenizer stk = new StringTokenizer(br.readLine(), " ");
int t = Integer.parseInt(stk.nextToken());
int x = Integer.parseInt(stk.nextToken());
int y = Integer.parseInt(stk.nextToken());
//run
insert(t,x,y);
// debugPrint(i, "insert"); //debug
delete();
// debugPrint(i, "delete"); //debug
zeroOne();
// debugPrint(i, "zeroOne"); //debug
}
//output
System.out.println(result);
int result2 = 0;
for(int i=0; i<6;i++){
for(int j=0; j<6; j++){
if(B[i][j]!=0)result2++;
if(G[i][j]!=0)result2++;
}
}
System.out.println(result2);
}
public static void debugPrint(int i, String name){
//debug
for(int j=0; j<4;j++)
System.out.println(Arrays.toString(B[j]));
System.out.println(i+"번 "+name+" Blue");
for(int j=0; j<6;j++)
System.out.println(Arrays.toString(G[j]));
System.out.println(i+"번 "+name+" Green");
}
느낀점
debug로 출력문을 찍어보면서 함수 하나하나 구현할 때 잘 동작하는지 찍어보길 추천
댓글남기기