문제링크 입니다

🚀 [LOAN] 문제 😊😊😊😊😊

집을 떠나 혼자 살게 된 재훈이는 회사 근처의 전세집을 알아보고 있습니다. 전세금은 N원인데, 재훈이는 이것을 연이율 P%로 대출받을 수 있습니다. 재훈이는 M개월 동안 매달 일정액 C원씩을 갚으려고 합니다.

대출의 잔금은 대출 기간 동안 다음과 같이 변화합니다.

  • 대출의 잔금은 대출 금액 N원에서 시작합니다.
  • 한 달이 지날 때마다 대출 잔금이 월 이자 (P/12)% 만큼 불어납니다.
  • 이자가 추가된 다음 월 상환액 C를 대출 잔금에서 제합니다.

M개월 걸려 모든 대출 금액을 갚기 위해서는 한 달에 최소 얼마씩을 갚아야 할까요?

🔑 [풀이]

원금에 이자를 갚은 방법을 이분법을 통해 빠르게 푸는 문제였습니다. 코드를 보시면 쉽게 알 수 있을 겁니다.

⌨️ 입력

입력의 첫 줄에는 테스트 케이스의 수 T(<= 50)가 주어집니다. 각 테스트 케이스는 3개의 수 N, M, P(1 <= N <= 100,000,000, 1 <= M <= 120, 0 < P <= 50)으로 주어집니다. N과 P는 실수이며, M은 정수입니다.

🖥 출력

각 테스트 케이스마다 한 줄에 한 달마다 상환할 금액 C를 출력합니다. 10-7 이하의 절대/상대 오차가 있는 답은 정답으로 인정됩니다.

🖱 입력 예제

4
20000000 12 6.8
35000000 120 1.1
40000000 36 0.5
100 120 0.1

💻 출력 예제

1728691.4686372071
308135.8967737053
1119696.7387703573
0.8375416659

💎 전체 코드는 다음과 같습니다.

//
//  LOAN.cpp
//  AALGGO
//
//  Created by inhyeok on 2021/11/08.
//
#include <iostream>
#include <fstream>
using namespace std;

ifstream fin("LOAN.txt");
// 대출 잔금은 ?
double balance(double amount, int duration, double rates, double monthlyPayment){
    double balance = amount; // 남은 대출금
    for(int i =0; i<duration; i++){
        balance *= (1+ (rates/12)/100.0 ); // 한달에 이자가 붙음.
        balance -= monthlyPayment; // 한달에 이만큼 갚은만큼 뺀다.
    }
    return balance;
}

// 한달에 갚아야할 최소 금액을 리턴
double payment(double amount, int duration, double rates){
    // 한달간 갚아야할 금액을 lo, hi 로 표현;
    // hi = 원금 + 이자.
    double lo = 0, hi = amount*(1+ (rates/12)/100);
    for(int it=0; it<100; it++){
        double mid = (lo+hi)/2.0;
        if(balance(amount,duration,rates,mid)<=0){
            hi = mid;
        }
        else{
            lo = mid;
        }
    }
    return hi;
}
int main(){
    int test_case;
    fin >> test_case;
    for(int test=0; test < test_case; test++){
        double N , P; // N -> 대출 금액, P -> 월 이자(P/12)%
        int M; // 개월수, 갚아야할 M 개월
        fin >> N >> M >> P ;
        printf("%0.10f\n",payment(N,M,P));
    }
}

LOAN

Comments