블로그 옮겼습니다
Codeground) 윤목의 달인 본문
1<= P <= 5
인 실수 P 가 입력으로 들어오는데 최대 소수점은 9번째자리까지이다.
윤목은 한번 시행했을 때 1~5점을 얻게되는데 여러번 시행했을 때 최소 시행 횟수로
평균 점수가 정확히 p가 되기 위하여 각 점수를 몇번씩 획득해야하는지 구하는 문제이다.
어떤 주어진 소수를 정수로 만들기 위해 곱해야 하는 최소 정수를 구하면 그게 바로 총 시행 횟수의 최소값이 될 것이다.
이 때 구하는 방법은 여기를 참고
이 시행 횟수를 C라고 해보자. 그러면 P*C 는 그 때의 점수의 총 합이 될 것인데, 이것을 S라고해보자.
그럼 1~5점을 C번 골라서 S가 되는 경우를 하나만 찾으면 된다.
조금만 생각해보면 답은 여러개가 될 수 있다는 것을 알 수가 있다. 두 점수의 합이 4가 되는경우가
2점+2점 과 1점+3점 이 있다는 것만 봐도 알 수가 있다. 우린 그럼 이 경우의 수중에 딱 한개만 고르면
될 것이다. 우리는 그래서 그리디하게 구할 것이다. 우선 식을 두개 써보자
a + 2*b + 3*c + 4*d + 5*e = S .... 1번식
a + b + c + d + e = C .... 2번식
1번식에서 2번식을 빼보자. 그럼
b + 2*c + 3*d + 4*e = S - C
가 된다. 그럼 이 식을 만족하는 b, c, d, e 조합을 하나만 구하면 되는데 만약 b 를 S - C로 주고
c, d, e 를 0으로 줘보면 어떻게 될까? b가 매우 커져서 C보다 커질 수가 있고 그러면
2번식을 만족할 수 없게 된다. 왜냐하면 시행횟수는 무조건 음이아닌 정수이기 때문이다.
그러면 고득점을 최대한 많은 횟수를 할당하고 나머지 남는 점수를 저득점에 할당하는 식으로 해보자.
고득점에 최대한 많은 수를 할당했다면 저득점의 시행 횟수는 클 수가 없기 때문에 b + c + d + e 는
최소가 될 수밖에 없고 그러면 2번식에서 b~e 를 우변으로 넘겨서 나오는 식인
a = C - b - c - d - e
를 풀면 a의 개수를 구할 수가있다. 만약 (b + c + d + e) 가 C 보다 커서 a가 음수가 되어야 하는 경우가
나올 수 있을까 걱정할 수가 있는데, 우리는 그리디 하게 b + c + d + e 를 최대한 작게 해줬는데도
C보다 크다면 애초에 이것은 1번식과 2번식을 모두 만족하는 a,b,c,d,e 조합이 존재하지 않는다는 말이(될 것같)다.
근데 왠지 조합은 무조건 존재한다. 왜냐하면 1~5점 C 개로 만들 수 있는 총점은 C~5*C 점 이기 때문에
이것을 C로 나눠 나오는 평균 점수인 P를 1~5인 모든 실수에 대해 만들 수가 있다.(아마도)
그래서 모순이므로 그리디하게 하면 된다..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <bits/stdc++.h> using namespace std; typedef long long ll; const int mod = 1e9+7; const int inf = 0x3c3c3c3c; const long long infl = 0x3c3c3c3c3c3c3c3c; int T; double P; ll ans[5]; ll gcd(ll a, ll b){ return b ? gcd(b, a % b) : a; } int main() { cin >> T; for(int t = 1; t <= T; t++){ memset(ans,0,sizeof(ans)); cin >> P; ll S = 1e12; ll GCD = gcd(P*S, S); ll C = S/GCD; S = P * C; S -= C; ans[4] = S/4; if(S%4) ans[S%4]++; ans[0] = C - ans[1] - ans[2] - ans[3] - ans[4]; cout << "#testcase" << t << "\n"; for(int i = 0 ; i < 5; i++) cout << ans[i] << " "; cout << endl; } return 0; } | cs |
'Algorithm > Problem Solving' 카테고리의 다른 글
CSacademy) Second Minimum (0) | 2017.06.01 |
---|---|
알고스팟) COUNTPALIN (0) | 2017.05.31 |
Topcoder SRM 522 Div1(Medium) CorrectMultiplication (0) | 2017.05.20 |
BOJ 14276번 도로 건설 (0) | 2017.05.11 |
Hackerrank) Tree Pruning (0) | 2017.05.11 |