문제 링크
주의사항
- JAVA를 사용하여 프로그램을 사용하였습니다.
- 백준에서 코드를 작성하였을 때 아래 형태에서 Main에서 결과가 출력되어야 합니다.
public class Main{
public static void main(String[] args){
}
}
문제 설명
문제 내용이 많아서 핵심적인 부분만 보여드리고 전체는 링크를 들어가셔서 확인해주시면 감사하겠습니다.
접근 방법
이 문제에 핵심은
1. 3가지 모양의 도형이 오른쪽, 아래쪽 방향으로 이동하면서 채워간다.
2. 행이나 열이 완성되면 없어지고 한 칸씩 땡겨진다.
3. 연한색 구간에 도형이 있을 경우 그 열이나 행 개수만큼 가장 아래 구간을 제거 및 땡겨집니다.
4. 모든 도형의 이동이 이루어진 뒤에 모형이 존재하는 칸의 개수를 결과로 출력합니다.
알고리즘 진행 순서.
1. 입력되는 정보들을 저장합니다.
2. 문제에서 설명한 내용을 그대로 시뮬레이션을 진행하였습니다.
3. 모든 도형에 시뮬레이션 종료 후 존재하는 칸의 개수를 결과로 출력합니다.
예제입력 1~7까지 진행과정을 문제에서 그림으로 보여주고 있습니다.
- BufferedReader를 사용하여 입력 값을 받았습니다.
- StringTokenizer를 이용하여 입력된 정보에 대하여 나누었습니다.
- blueMove, greenMove을 실행하여 시뮬레이션을 진행합니다.
- 시뮬레이션 종료 후 점수와 getMap을 통해 도형이 남은 칸의 개수를 BufferedWriter 저장하였습니다.
- BufferedWriter에 저장된 결과값을 출력하였습니다.
- blueMove,greenMove함수는 blueComplete, lightBlueCheck.... 을 이용하여 시뮬레이션을 진행합니다.
- blueComplete, greenComplete함수는 도형 이동 후 도형에 따라 행이나 열이 완성되는 것을 확인, 변경하는 함수들을 호출합니다.
- blueValueMove, greenValueMove함수는 값들을 땡기는 역활을 수행합니다.
- blueColCheck, greenRowCheck함수는 각 행이나 열이 완성되었는지 확인합니다.
- lightBlueCheck, lightGreenCheck함수는 연한 부분에 도형이 존재하는 칸이 있는지 확인합니다.
- getMap함수는 시뮬레이션 종료 후 초록색, 파란색에 남아있는 도형이 있는 칸의 개수를 구합니다.
import java.io.*;
import java.util.StringTokenizer;
public class Main {
static int N, point = 0;
static int[][] green = new int[6][4]; //초록색 구역
static int[][] blue = new int[4][6]; //파란색 구역
public static void main(String[] args) throws IOException {
//입력값 처리하는 BufferedReader
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//결과값 출력하는 BufferedWriter
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
N = Integer.parseInt(br.readLine());
StringTokenizer st;
//도형 정보 저장 및 시뮬레이션 진행
for(int i=0;i<N;i++) {
st = new StringTokenizer(br.readLine(), " ");
int t = Integer.parseInt(st.nextToken());
int x = Integer.parseInt(st.nextToken());
int y = Integer.parseInt(st.nextToken());
blueMove(t, x); //도형 파란색 칸으로 이동
greenMove(t, y); //도형 초록색 칸으로 이동
}
bw.write( point + "\n" + getMap()); // 결과 BufferedWriter 저장
bw.flush(); //결과 출력
bw.close();
br.close();
}
//도형 → 파란색 방향으로 이동
static void blueMove(int t, int x){
int col = 5;
if(t==1){
for(int i=2;i<7;i++){
if(i==6){
blue[x][5] = 1;
break;
}
if(blue[x][i] == 1){
blue[x][i-1] = 1;
col = i-1;
break;
}
}
}else if(t==2){
for(int i=2;i<7;i++){
if(i==6){
blue[x][5] = 1;
blue[x][4] = 1;
break;
}
if(blue[x][i] == 1){
blue[x][i-1] = 1;
blue[x][i-2] = 1;
col = i-1;
break;
}
}
}else{
for(int i=2;i<7;i++){
if(i==6){
blue[x][5] = 1;
blue[x+1][5] = 1;
break;
}
if(blue[x][i] == 1 || blue[x+1][i]==1){
blue[x][i-1] = 1;
blue[x+1][i-1] = 1;
col = i-1;
break;
}
}
}
blueComplete(t, col); //이동 후 완성된 열이 있는지 확인
//연한 부분 탐색
int minus = lightBlueCheck(1) + lightBlueCheck(0);
if(minus!=0) //연한 부분에 도형 존재시 해당 칸만큼 땡기기
blueValueMove(minus, 5);
}
//연한 부분 탐색하는 함수
static int lightBlueCheck(int col){
for(int i=0;i<4;i++)
if(blue[i][col]==1) //도형 존재시.
return 1;
return 0;
}
//도형 파란색 부분 이동 후 열 확인하는 함수
static void blueComplete(int t, int col){
if(t==1 || t==3){
if(blueColCheck(col) == 0)
return;
blueValueMove(1, col);
point++;
}else{
int t1 = blueColCheck(col);
int t2 = blueColCheck(col-1);
if (t1 + t2==0)
return;
if(t1==0 && t2 == 1)
blueValueMove(1, col-1);
else
blueValueMove(t1 + t2, col);
point+=t1 + t2;
}
}
//연한 파란색에 도형이 있거나 열이 완성된 경우 땡겨지는 것 진행하는 함수
static void blueValueMove(int minus, int col){
for(int i=col;i >= minus; i--) {
for (int j = 0; j < 4; j++)
blue[j][i] = blue[j][i - minus];
}
blue[0][0] = blue[1][0] = blue[2][0] = blue[3][0] = 0;
if(minus==2)
blue[0][1] = blue[1][1] = blue[2][1] = blue[3][1] = 0;
}
//해당 열의 칸에 모두 도형이 존재하는지 확인하는 함수
static int blueColCheck(int col){
for(int i=0;i<4;i++)
if(blue[i][col]==0)
return 0;
return 1;
}
//도형 ↓ 초록색 방향으로 이동
static void greenMove(int t, int y){
int row = 5;
if(t==1){
for(int i=2;i<7;i++){
if(i==6){
green[5][y] = 1;
break;
}
if(green[i][y] == 1){
green[i-1][y] = 1;
row = i-1;
break;
}
}
}else if(t==2){
for(int i=2;i<7;i++){
if(i==6){
green[5][y] = 1;
green[5][y+1] = 1;
break;
}
if(green[i][y] == 1 || green[i][y+1]==1){
green[i-1][y] = 1;
green[i-1][y+1] = 1;
row = i-1;
break;
}
}
}else{
for(int i=2;i<7;i++){
if(i==6){
green[4][y] = 1;
green[5][y] = 1;
break;
}
if(green[i][y] == 1){
green[i-1][y] = 1;
green[i-2][y] = 1;
row = i-1;
break;
}
}
}
greenComplete(t, row); ////이동 후 완성된 행이 있는지 확인
//연한 부분 탐색
int minus = lightGreenCheck(1) + lightGreenCheck(0);
if(minus!=0) //연한 부분에 도형 존재시 해당 칸만큼 땡기기
greenValueMove(minus, 5);
}
//연한 부분 탐색하는 함수
static int lightGreenCheck(int row){
for(int i=0;i<4;i++)
if(green[row][i]==1)
return 1;
return 0;
}
//도형 초록색 부분 이동 후 행 확인하는 함수
static void greenComplete(int t, int row){
if(t==1 || t==2){
if(greenRowCheck(row) == 0)
return;
greenValueMove(1, row);
point++;
}else{
int t1 = greenRowCheck(row);
int t2 = greenRowCheck(row-1);
if (t1 + t2==0)
return;
if(t1==0 && t2 == 1)
greenValueMove(1, row-1);
else
greenValueMove(t1 + t2, row);
point += t1 + t2;
}
}
//연한 초록색에 도형이 있거나 행이 완성된 경우 땡겨지는 것 진행하는 함수
static void greenValueMove(int minus, int row){
for(int i=row;i >=minus; i--) {
for (int j = 0; j < 4; j++)
green[i][j] = green[i-minus][j];
}
green[0][0] = green[0][1] = green[0][2] = green[0][3] = 0;
if(minus==2)
green[1][0] = green[1][1] = green[1][2] = green[1][3] = 0;
}
//해당 행의 칸에 모두 도형이 존재하는지 확인하는 함수
static int greenRowCheck(int row){
for(int i=0;i<4;i++)
if(green[row][i]==0)
return 0;
return 1;
}
//파란색, 초록색 부분에 도형이 남아있는 칸의 개수를 구하는 함수
static int getMap(){
int result = 0;
for(int i=0;i<4;i++){
for(int j=0;j<6;j++)
result += blue[i][j];
}
for(int i=0;i<6;i++){
for(int j=0;j<4;j++)
result += green[i][j];
}
return result;
}
}
'백준' 카테고리의 다른 글
[백준] code.plus(시뮬레이션과 구현,JAVA)19236번, 청소년 상어 (0) | 2022.08.15 |
---|---|
[백준] code.plus(브루트 포스 Part 1,JAVA)16968번, 차량 번호판 1 (0) | 2022.08.14 |
[백준] code.plus(시뮬레이션과 구현,JAVA)16939번, 2×2×2 큐브 (0) | 2022.08.13 |
[백준] code.plus(시뮬레이션과 구현,JAVA)16974번, 레벨 햄버거 (0) | 2022.08.11 |
[백준] code.plus(시뮬레이션과 구현,JAVA)17822번, 원판 돌리기 (0) | 2022.08.10 |
댓글