A - 鉛筆 (Pencils) Editorial by TumoiYorozu


この解説は、C++ に入門したばかりの中高生レベルを想定して、考察の方法、コードの書き方の解説をします。

セットXかセットYのどちらかのみを使ってN本の鉛筆を揃えるので、

  • セットXで揃えた場合
  • セットYで揃えた場合

の2つを計算して、それらのうち小さかったほうを答えれば良い。

実装のヒント1 : どの順番で考えればよいか

実装の手順としては

  1. セットXで揃えた場合、セットXを何セット買えばよいかを求める
  2. セットYで揃えた場合、セットYを何セット買えばよいかを求める
  3. セットXで揃えた場合の必要な価格を求める
  4. セットYで揃えた場合の必要な価格を求める
  5. 求めた2つの価格を比較して、小さい方を出力する
の順番で考えれば良い。

実装のヒント2

セットXを何セット買えばよいかは、 $\lceil \frac{N}{A} \rceil$、つまり $N \div A$の切り上げを考えれば良い。

例えば1セット3本で10本揃えたいならば、$\lceil \frac{10}{3} \rceil = \lceil 3.333... \rceil = 4$ (セット)必要である。

どうにかして四則演算で切り上げを求めることはできないだろうか? 一度、じっくり考えてみよう!

(四則演算だけで計算することも出来るが、if を用いても表現できる)

if で書く時のヒント
例えば
if (N % A != 0) {
    処理
}
と書くと、NがAの倍数じゃない場合の処理を書くことが出来る。他にも
if (N % A == 0) {
    N が A の倍数のときの処理
} else {
    N が A の倍数じゃないときの処理
}
の様な書き方でも実現できるだろう。

(次のヒントで切り上げの方法を書きます。)

実装のヒント3

$N \div A$の切り上げは

(N + A - 1) / A
で求める事ができる。

他にも、今回はNが正の数であるので

(N - 1) / A + 1;
でも求められる。(Nが0以下のとき、負の数の割り算をすることになるが、C++では負の数の割り算は混乱のもとになるので初心者のうちはおすすめしない)

他にも、わざわざ1文で書かなくても、if文を用いて考えても良い。

int Xnum = N / A;
if (N % A != 0) {
    Xnum += 1;
}
(N % A != 0) は N を A で割った余りが0かどうか、つまり N が A の倍数かどうかを調べている。 これは、NがAの倍数であれば、N / Aをそのまま使えばよく、NがAの倍数では無いときは、1を加えることで調整をしている。 また、同様に以下のようなコードでも良い。
int Xnum;
if (N % A == 0) {
    Xnum = X/A;
} else {
    Xnum = X/A + 1;
}

同様にセットYも何セット必要かを計算して、それぞれの必要な価格を求めて、比較を行えば、ACはすぐそこである!

解答コード

コード例 (実際の提出のリンクはこちら)

#include <bits/stdc++.h>
using namespace std;
int main(){
    int N, A, B, C, D;
    cin >> N >> A >> B >> C >> D;

    // セットXでそろえる時の、必要なXのセット数
    int Xnum = (N + A - 1) / A;

    // セットYでそろえる時の、必要なYのセット数
    int Ynum = (N + C - 1) / C;

    // セットX,Yそれぞれで揃える時、必要な金額
    int Xyen = Xnum * B;
    int Yyen = Ynum * D;

    // 2つの金額を比較して、小さい方を出力する
    if (Xyen <= Yyen) {
        cout << Xyen << endl;
    } else {
        cout << Yyen << endl;
    }
}

posted:
last update: