🚀 [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));
}
}
Comments