C++の練習を兼ねて, 競プロ典型 90 問 の 問題016 (Minimum Coins) を解いてみた.
■感想.
1. 実装方針を決めることができたので, AC版に到達出来たと思う.
2. 手強い問題が非常に多い気もするけど, 時間を見つけて, 引き続き, 取り組んでいきたいと思う.
詳細は, 本家のサイト(GitHub) 競プロ典型 90 問 の 問題016 を ご覧下さい.
■C++版プログラム(問題016/AC版).
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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
// C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; using LL = long long; #define repex(i, a, b, c) for(int i = a; i < b; i += c) #define repx(i, a, b) repex(i, a, b, 1) #define rep(i, n) repx(i, 0, n) #define repr(i, a, b) for(int i = a; i >= b; i--) int main(){ // 1. 入力情報. LL N, coin[3]; scanf("%lld %lld %lld %lld", &N, &coin[0], &coin[1], &coin[2]); // 2. sort. sort(coin, coin + 3); // 3. 硬貨枚数を計算. int ans = 10000; // ex. // 15円 を 1, 5, 8円で支払う場合, // 1, 1, 5, 8 とすると, 4枚. // 5, 5, 5 とすると, 3枚. // のように, 硬貨枚数が変化することに注意. repr(c, 9999, 0){ // 金額がオーバーする場合. LL mc = coin[2] * c; if(mc > N) continue; // ぴったりの場合. if(mc == N) ans = min(ans, c); // 不足する場合. if(mc < N){ LL mab = N - mc; if(mab / coin[1] > 9999) continue; int bMax = (int)(mab / coin[1]); repr(b, bMax, 0){ LL ma = mab - coin[1] * b; int a = (int)(ma / coin[0]); if(ma % coin[0] == 0){ ans = min(ans, a + b + c); break; } } } } // 4. 出力. assert(ans != 10000); printf("%d\n", ans); return 0; } |
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 36 37 38 39 40 41 42 43 44 45 |
[入力例] 227 21 47 56 [出力例] 5 ※AtCoderテストケースより [入力例] 9999 1 5 10 [出力例] 1004 ※AtCoderテストケースより [入力例] 998244353 314159 265358 97932 [出力例] 3333 ※AtCoderテストケースより [入力例] 100000000 10001 10002 10003 [出力例] 9998 ※AtCoderテストケースより [入力例] 1000000000 314159 265358 97932 [出力例] 3527 [入力例] 987654321 14142 135623 73095 [出力例] 7405 |
■参照サイト
016 – Minimum Coins