관리 메뉴

LC Studio

백준 2869 달팽이는 올라가고 싶다 (JAVA) 본문

Java/백준 알고리즘

백준 2869 달팽이는 올라가고 싶다 (JAVA)

Leopard Cat 2022. 3. 19. 16:44

문제

땅 위에 달팽이가 있다. 이 달팽이는 높이가 V미터인 나무 막대를 올라갈 것이다.

달팽이는 낮에 A미터 올라갈 수 있다. 하지만, 밤에 잠을 자는 동안 B미터 미끄러진다. 또, 정상에 올라간 후에는 미끄러지지 않는다.

달팽이가 나무 막대를 모두 올라가려면, 며칠이 걸리는지 구하는 프로그램을 작성하시오.

입력

첫째 줄에 세 정수 A, B, V가 공백으로 구분되어서 주어진다. (1 ≤ B < A ≤ V ≤ 1,000,000,000)

출력

첫째 줄에 달팽이가 나무 막대를 모두 올라가는데 며칠이 걸리는지 출력한다.

별로 어렵지 않아 보이는 문제이지만,

시간제한이 0.15 초 (추가 시간 없음)이기 때문에 출력을 최대한 빨리해야한다.

그래서 BufferedReader와 BufferedWriter을 활용해줬다.

 

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 IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        StringTokenizer st = new StringTokenizer(br.readLine());
        br.close();
        int A = Integer.parseInt(st.nextToken()); 
        int B = Integer.parseInt(st.nextToken());
        int V = Integer.parseInt(st.nextToken());
        
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
  
        while(true){
            if(V <= (A*i)-(B*(i-1))){
                String string = Integer.toString(i);
                bw.write(string);
                bw.flush();
                bw.close();
                break;
            }
            else{
                i++;
            }       
        }      
    }
}

A,B,V를 입력받아 i번의 횟수를 중심으로 식을 작성했다.

하지만 시간초과가 나왔다... Buffered를 활용하는 것만으로는 부족했나보다.

 

1712번 손익분기점 문제를 풀었을때를 되돌아보았다.

그때 반복문을 쓰지않고 식을 세워 문제를 해결하는 방법을 배웠었다.

이번 문제에 적용해 보았다.

 

V(높이)
A(올라가는 높이)

B(내려가는 높이)
i(날짜)

 

높이가 같아질때를 기준으로 식을 세워보았다.

(높이) = (올라가는 높이 * 날짜) - (내려가는 높이 * (날짜 - 1))    

//날짜 -1을 한 이유는, 문제에서 정상에 올라간 후에는 미끄러지지 않는다고 했기 때문에 해주었다.
V = (A*i) - (B*(i-1))
V = (A*i) - (B*i - B)
V = (A-B)*i +B
V-B = i(A-B)
(V-B)/(A-B) = i

위와 같은 식으로 i를 구할 수 있다.

 

다만, 정수로 딱 나눠떨어지지 않는 경우에는 날짜에 +1을 해주어야 한다.

왜냐하면 1.5, 1.6 등의 날짜가 나오면 0.5, 0.6도 우리는 하나라고 치기 때문이다.

코드를 작성해보면->

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 IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        
        StringTokenizer st = new StringTokenizer(br.readLine());
        br.close();
        int A = Integer.parseInt(st.nextToken());
        int B = Integer.parseInt(st.nextToken());
        int V = Integer.parseInt(st.nextToken());
        
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
        /*
        while(true){
            if(V <= (A*i)-(B*(i-1))){
                String string = Integer.toString(i);
                bw.write(string);
                bw.flush();
                bw.close();
                break;
            }
            else{
                i++;
            }       
        }
        */
        
        if((double)(V-B)/(A-B) == (V-B)/(A-B)){ //정수로 딱 나눠질경우
            String string = Integer.toString((V-B)/(A-B));
            bw.write(string);
            bw.flush();
            bw.close();
        }
        else{//나머지가 생길경우
            String string = Integer.toString((V-B)/(A-B)+1); 
            bw.write(string);
            bw.flush();
            bw.close();
        }
        
    }
}

위와같이 하면 된다! 정답!

반응형