하루하루 꾸준히, 인생은 되는대로

알고리즘

백준 2502 떡 먹는 호랑이 C++

긤효중 2022. 5. 25. 17:13

https://www.acmicpc.net/problem/2502

 

2502번: 떡 먹는 호랑이

첫줄에 첫 날에 준 떡의 개수 A를 출력하고 그 다음 둘째 줄에는 둘째 날에 준 떡의 개수 B를 출력한다. 이 문제에서 주어진 D, K에 대해서는 항상 정수 A, B (1≤ A ≤ B)가 존재한다. 

www.acmicpc.net

문제

하루에 한 번 산을 넘어가는 떡 장사 할머니는 호랑이에게 떡을 주어야 산을 넘어갈 수 있는데, 욕심 많은 호랑이는 어제 받은 떡의 개수와 그저께 받은 떡의 개수를 더한 만큼의 떡을 받아야만 할머니를 무사히 보내 준다고 한다. 

예를 들어 첫째 날에 떡을 1개 주었고, 둘째 날에는 떡을 2개 주었다면 셋째 날에는 1+2=3개, 넷째 날에는 2+3=5개, 다섯째 날에는 3+5=8개, 여섯째 날에는 5+8=13개를 주어야만 무사히 산을 넘어갈 수 있다. 

우리는 산을 무사히 넘어온 할머니에게 오늘 호랑이에게 몇 개의 떡을 주었는지, 그리고 오늘이 호랑이를 만나 떡을 준지 며칠이 되었는지를 알아내었다. 할머니가 호랑이를 만나서 무사히 넘어온 D째 날에 준 떡의 개수가 K개임을 알 때, 여러분은 할머니가 호랑이를 처음 만난 날에 준 떡의 개수 A, 그리고 그 다음 날에 호랑이에게 준 떡의 개수 B를 계산하는 프로그램을 작성하시오. 이 문제에서는 항상 1 ≤ A ≤ B 이다.

예를 들어 여섯 번째 날에 산을 무사히 넘어온 할머니가 호랑이에게 준 떡이 모두 41개라면, 호랑이를 만난 첫 날에 준 떡의 수는 2개, 둘째 날에 준 떡의 수는 7개이다. 즉 셋째 날에는 9개, 넷째 날에는 16개, 다섯째 날에는 25개, 여섯째 날에는 41개이다. 따라서 A=2, B=7 이 된다. 단 어떤 경우에는 답이 되는 A, B가 하나 이상일 때도 있는데 이 경우에는 그 중 하나만 구해서 출력하면 된다.


입력

첫째 줄에는 할머니가 넘어온 날 D (3 ≤ D ≤ 30)와 그 날 호랑이에게 준 떡의 개수 K (10 ≤ K ≤ 100,000)가 하나의 빈칸을 사이에 두고 주어진다. 


출력

첫줄에 첫 날에 준 떡의 개수 A를 출력하고 그 다음 둘째 줄에는 둘째 날에 준 떡의 개수 B를 출력한다. 이 문제에서 주어진 D, K에 대해서는 항상 정수 A, B (1≤ A ≤ B)가 존재한다. 


첫쨰 날에 준 떡의 개수를 A라 하고 , 둘쨰 날에 준 떡의 개수를 B라고 하자.

3번쨰날은 A+B만큼의 떡이 존재하고, 4번쨰날은 A+B (3번쨰) + B(2번쨰) 만큼의 떡이 존재한다.

즉,dp[i]를 i번쨰 날의 떡의 개수라고 한다면 dp[i]는 dp[i-1]과 dp[i-2]를 더한 값이 된다.

최종적으로 n번째 날에는 dp[n]에 떡의 개수가 담길 것이고, 결과적으로 x * A + y * B의형태가 될 것이다.

이 값이 k를 만족하는 수를 찾아야한다.

 

#include <iostream>
using namespace std;
struct data{ //n번쨰 날의 떡의 개수를 표현하는 구조체 (A의개수 + B의 개수)
    int a;
    int b;
};
 
typedef struct data d;
 
int main(void){
    int n,k;
    cin >> n >> k;
    d arr[32];
    for(int i = 1;i<=n;i++){
        if(i == 1){
            arr[i].a = 1;
            arr[i].b = 0;
        }
        else if(i == 2){
            arr[i].a = 0;
            arr[i].b = 1;
        }
        else{ //i번쨰 떡의 점화식
            arr[i].a = arr[i-1].a + arr[i-2].a;
            arr[i].b = arr[i-1].b + arr[i-2].b;
        }
    }
    int final_a = 0;
    int final_b = 0;
    int sum = 0;
 
    /*arr[n]*.a * i + arr[n].b * j를 만족하는 i와 j 찾기
    */
    for(int i = 1;i*arr[n].a<=k;i++){ 
        for(int j = 1;j*arr[n].b<=k;j++){
            sum = (arr[n].a * i) + (arr[n].b * j);
 
            if(sum == k){
                cout << i << '\n';
                cout << j;
                return 0;
            }
        }
    }
 
 
}

 

'알고리즘' 카테고리의 다른 글

백준 14405 피카츄 C++  (0) 2022.05.30
백준 1343 폴리오미노 C++  (0) 2022.05.29
백준 11508 C++  (0) 2022.05.25
알고리즘 스터디 10주차  (0) 2022.05.23
백준 9324 진짜 메시지 C++  (0) 2022.05.18