けんちょんの競プロ精進記録

競プロの精進記録や小ネタを書いていきます

AtCoder ABC 209 A - Counting (灰色, 100 点)

とても教育的な問題!

問題概要

整数  A, B が与えられる。

 A 以上  B 以下の整数は何個あるか?

解法

まず、 A \gt B の場合は、 A 以上  B 以下の整数は存在しないことに注意しよう。この場合は 0 個と答えれば良い。

それでは、 A \le B としよう。この場合は、 A 以上  B 以下の整数の個数は、


 B - A + 1


となる。 B - A ではないことに注意しよう。これはもう憶えてしまっても良いくらいだと思う。とても大事な考え方だ!

具体例をあげると、たとえば  A = 3 B = 7 のとき、3 以上 7 以下の整数は

3, 4, 5, 6, 7

の 5 個ある。7 - 3 + 1 = 5 より、確かに合っている。

#include <bits/stdc++.h>
using namespace std;

int main() {
    int A, B;
    cin >> A >> B;
    
    if (A <= B)
        cout << B - A + 1 << endl;
    else
        cout << 0 << endl;
}

AtCoder ABC 208 A - Rolling Dice (灰色, 100 点)

「この数からこの数の間の数はすべて作れる」という考え方をする問題。この考え方は、より高度な問題では頻出!

問題概要

1〜6 の目が出るサイコロを  A 回振った。

出た目の総和が  B になることがありうるかどうかを判定せよ。

解法

これは難しい!!!

こういう時には、「出た目の総和が  B にできない場合ってどんな場合だろう......」と考えてみると、活路が開けることが多い。

たとえば、 A = 3 B = 20 の場合はあり得ない。なぜなら、3 回の目の和として考えられる最大値は

 6 \times 3 = 18

であり、それを超過しているからだ。また、 A = 3 B = 2 の場合もあり得ない。なぜなら、3 回の目の和として考えられる最小値は

 1 \times 3 = 3

であり、それよりも小さいからだ。

一般に、 A 回ふって出た目の和の最小値は  A、最大値は  6A になるから、次のことが言える。


 A \le B \le 6A でなければならない


 A 6A の間はすべて作れること

では、この  A 6A の間の数はすべて作れるだろうか? この答えは Yes だ!!!!!

考えやすくするため、 B 個のアメを  A 人に配るという設定にして考えてみよう。ただし、1 人のもらう個数は 1〜6 個のいずれかでなければならないとしよう。

たとえば  A = 3 B = 14 という場合を考えてみよう。

 14 \div 3 = 4 あまり 2

であることに注意しよう。

よって、14 個のアメをまず 3 人に 4 個ずつ配り、そして残った 2 個を 2 人に配れば良い。つまり、

 5 + 5 + 4 = 14

となる。 A = 3 B = 14 の場合はこうして実現できた。

他に、一般に、 A \le B \le 6A さえ満たしていれば、同様の方法で実現できる。

まとめ

以上から、次の条件を満たせば "Yes"、そうでなければ "No" だ。


 A \le B \le 6A


コード

#include <bits/stdc++.h>
using namespace std;

int main() {
    int A, B;
    cin >> A >> B;
    
    int min_value = A;
    int max_value = 6 * A;
    
    if (min_value <= B && B <= max_value)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;
}

AtCoder ABC 207 A - Repression (灰色, 100 点)

頭を柔らかくして考えよう。

問題概要

3 個の整数  A, B, C から 2 個選んで和をとる。

この和の最大値を求めよ。

解法

3 個の整数  A, B, C から 2 個選んだ和は

  •  A + B
  •  B + C
  •  C + A

の 3 通りがある。これらの最大値を求めればよい。

#include <bits/stdc++.h>
using namespace std;

int main() {
    int A, B, C;
    cin >> A >> B >> C;
    cout << max({A + B, B + C, C + A}) << endl;
}

AtCoder ABC 206 A - Maxi-Buying (灰色, 100 点)

出力がややこしい......

問題概要

税抜価格が  N 円の品物に対して、消費税 8% を乗せた税込価格と 206 円との大小比較をせよ。

(出力形式はリンク先から)

解法

税込価格は (int)(1.08 * N) で求めることができる。

#include <bits/stdc++.h>
using namespace std;

int main() {
    int N;
    cin >> N;
    
    int teika = (int)(1.08 * N);
    if (teika < 206)
        cout << "Yay!" << endl;
    else if (teika == 206)
        cout << "so-so" << endl;
    else
        cout << ":(" << endl;
}

AtCoder ABC 205 A - kcal (灰色, 100 点)

算数ではよくある「比」の問題

問題概要

100mL あたり  A kcal のドリンクがある。

 B mL で何 kcal でしょうか?

解法

求めるカロリーを  x kcal とする。比で表すと、次のようになる。

 100 : A = B : x

内項の積と外項の積は等しいから、

 100x = AB

よって、

 x = \displaystyle \frac{AB}{100}

と求められる。

今回は浮動小数点型で計算しよう。出力するときも、小数点以下ある程度出すようにしよう。

#include <bits/stdc++.h>
using namespace std;

int main() {
    double A, B;
    cin >> A >> B;
    double res = A * B / 100;
    cout << fixed << setprecision(10) << res << endl;
}