문제
등산가 김강산은 가족들과 함께 캠핑을 떠났다. 하지만, 캠핑장에는 다음과 같은 경고문이 쓰여 있었다.
캠핑장은 연속하는 20일 중 10일동안만 사용할 수 있습니다.
강산이는 이제 막 28일 휴가를 시작했다. 이번 휴가 기간 동안 강산이는 캠핑장을 며칠동안 사용할 수 있을까?
강산이는 조금 더 일반화해서 문제를 풀려고 한다.
캠핑장을 연속하는 P일 중, L일동안만 사용할 수 있다. 강산이는 이제 막 V일짜리 휴가를 시작했다. 강산이가 캠핑장을 최대 며칠동안 사용할 수 있을까? (1 < L < P < V)
시간 제한: 1초
메모리 제한: 128MB
입력
입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스는 한 줄로 이루어져 있고, L, P, V를 순서대로 포함하고 있다. 모든 입력 정수는 int범위이다. 마지막 줄에는 0이 3개 주어진다.
출력
각 테스트 케이스에 대해서, 강산이가 캠핑장을 최대 며칠동안 사용할 수 있는지 예제 출력처럼 출력한다.
예제 입력 | 예제 출력 |
5 8 20
5 8 17
0 0 0 | Case 1: 14
Case 2: 11 |
풀이
단순한 수학식과 브루트포스 방식으로 풀 수 있는 문제이다.
처음에, V일 짜리 휴가를 연속하는 P일로 나눈 나머지를 L일 만큼 곱한 뒤 남은 일 수를 더하면 되겠다고 단순하게 생각했다.
(V / P) * L + (V % P)
오답이 나와 반례를 찾아봤다.
1 20 39 0 0 0 output = 20 answer = 2
나머지 값이 가능한 날짜보다 큰 경우 오버한 것이다.
가능한 날짜보다 크면 가능한 날짜를 합하도록 수정했다.
int remain = (V % P) >= L ? L : (V % P); result = (V / P) * L + remain;
코드
첫번째 풀이
#include <iostream> #include <vector> using namespace std; int main() { vector<vector<int>> input; int L = -1, P = -1, V = -1, result = -1; // 가능/연속/총일/합 do { cin >> L >> P >> V; if (L && V && P) input.push_back({ L, P, V }); } while (L && V && P); for (int i = 0; i < input.size(); ++i) { L = input[i][0]; P = input[i][1]; V = input[i][2]; int remain = (V % P) >= L ? L : (V % P); result = (V / P) * L + remain; cout << "Case " << i + 1 << ": " << result << endl; } return 0; }
두번째 풀이
#include <iostream> #include <vector> using namespace std; int main() { int L = -1, P = -1, V = -1; vector<int> result; do { cin >> L >> P >> V; if (L && P && V) { int remain = V % P > L ? L : V % P; result.push_back((V / P) * L + remain); } } while (L && P && V); for (int i = 0; i < result.size(); ++i) { cout << "Case " << i + 1<< ": " << result[i] << "\n"; } return 0; }