본문 바로가기
끄적/Java_CT

[자바 코테]백준 1756번 피자굽기

by 밀키스 2022. 3. 12.

1. 문제 이해하기 

  1. 항아리에 피자를 하나씩 쌓는다. 각 층별로 피자의 크기보다 작다면 그 위에 피자를 쌓는다.
  2. 항아리의 각 층별 지름은 만일 위 층의 지름보다 크다면 위 층의 지름과 같게 재설정해도 상관 없다.
  3. 만일 피자가 단 한개라도 못들어가면 0을 반환한다. --> 이게 중요하다 난 모두 못들어갔을 때 0 출력하는 줄..

 

 

 


 

2. 코드 리뷰 

 

@ BufferedReader/Writer 와 StringTokenizer 

백준 알고리즘 문제를 처음 푸는데, 백줌 검색했을 때 가장 먼저 보였던 내용이다.

난 당연히 Scanner를 써서 입출력을 받으려 했지만 위의 2가지가 Scanner 보다 성능적인 면에서 좋다고 한다.

 


 

1. BufferedReader/Writer

 

BufferReader로 Scanner와 마찬가지로 데이터를 입력 받을 수 있다.

코드 본문에서는 "readline" 이란 표현을 썼는데 해당 명령어는 말 그대로 한줄을 쭉 읽어 들인다.

백준 입력을 보면 일반적으로 위처럼 공백을 구분자로 하여 데이터를 입력시킨다.

때문에 위 코드와 같이 한줄을 읽어들이면 데이터는 "7 3" /  "5 6 4 3 6 2 3"과 같이 들어간다.

이때 이것을 split 이나 슬라이싱을 사용해서 데이터를 구분할 수도 있지만 이와 관련하여 StringTokernizer가 있다.


2. StringTokernizer

 

해당하는 녀석은 한줄로 데이터를 입력 받았을 때 기본값으로 공백을 구분자로 하여 데이터를 받는다.

예로 내가 2번째 줄의 데이터를 입력 받았다면, nextToken( ) 명령어를 실행했을 때 "5"라는 데이터를 입력 받는다.

 

당연한 얘기지만 마지막 데이터를 입력 받고 다시 nextToken( ) 명령어를 실행하면 오류다. 범위를 벗어나니까.

 


@ 항아리에 들어간 마지막 피자 위치 구하기 

// 도착한 항아리 높이 구하기
int cnt=1;
int return_value =0;
for(int i=Depth-1;i>=0;i--) {
    if(piza_width<=oven_width[i]) {
        ++cnt;
        if(cnt>piza_cnt) {
            return_value=i+1;
            break;
        }
        if(i==0) {
            return_value=0;
            break;
        }
        piza_width = Integer.parseInt(st3.nextToken());
    }
}

 

  1. cnt와 return_value 변수는 각각 비교한 피자의 갯수와 내가 리턴할 값이다.
  2. 반복문은 항아리의 깊이(Depth)만큼 진행하며 피자의 지름 값(piza_width)과 항아리의 지름(oven_width)을 비교한다.
  3. 항아리가 해당되는 층에서 피자의 지름보다 크거나 같다면 더이상 피자가 못들어간다는 거니까 그때 cnt 값과 피자의 지름 값을 갱신해준다.
  4. 계속 진행하다 비교한 cnt의 갯수가 피자의 갯수(piza_cnt)보다 많다면 그때의 깊이를 저장하고 반복문을 종료한다
    1. 비교한 갯수가 피자의 갯수보다 많다는 말은 모든 피자에 대한 비교가 끝났다는 것. --> 오븐의 지름보다 피자의 지름 값이 작을때만 값이 오르는거니까
  5. 만일 cnt가 피자의 갯수까지 도달하지 못했다는것은 넣지 못한 피자가 존재한다는것. 때문에 반복변수의 값이 0이라면 0을 리턴해준다.

 


 

기본적으로 그렇게 어려운 문제는 아니였다. 시간이 거의 2시간은 걸렸는데... 이건

1. 이중 for문에 대한 시간초과를 고민해보는데 좀 시간이 걸렸다.
2. 문제를 제데로 이해하지 못한 상태로 진행을 했다.

 

이때 위의 2번 문제가 가장 중요하다..,.  나는 피자가 모두 못들어갔을 때 0이 반환되는거라 생각하고 풀었는데 계속 

틀렸습니다가 뜨길레.... 이것때문에 못해도 1시간은 더 고민했던것 같다...

 

다음에는 문제를 먼저 제데로 이해하고 진행해보자!!

 

 

 

전체코드

더보기
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 {

	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));
		
		// 항아리 깊이, 피자 갯수
		StringTokenizer st = new StringTokenizer(br.readLine());
		int Depth = Integer.parseInt(st.nextToken());
		int piza_cnt = Integer.parseInt(st.nextToken());
		
		// 항아리 내부 지름
		StringTokenizer st2 = new StringTokenizer(br.readLine());
		int[] oven_width = new int[Depth];
		for(int i=0; i<Depth; i++) {
			oven_width[i] = Integer.parseInt(st2.nextToken());
			if(i!=0) {
				oven_width[i] = oven_width[i] >oven_width[i-1] ? oven_width[i-1] : oven_width[i];
			}
		}
		
		// 만들어진 피자 지름
		StringTokenizer st3 = new StringTokenizer(br.readLine());
		int piza_width = Integer.parseInt(st3.nextToken());
        
		// 도착한 항아리 높이 구하기
		int cnt=1;
		int return_value =0;
		for(int i=Depth-1;i>=0;i--) {
			if(piza_width<=oven_width[i]) {
				++cnt;
                // 피자갯수만큼 했다면 값을 리턴하고 종료
				if(cnt>piza_cnt) {
					return_value=i+1;
					break;
				}
                // 피자갯수만큼 못했다면 0을 리턴
				if(i==0) {
					return_value=0;
					break;
				}
				piza_width = Integer.parseInt(st3.nextToken());
			}
		}
		
		bw.write(Integer.toString(return_value));
		
		br.close();
		bw.close();
		
	}
}

 

반응형

댓글