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

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

AtCoder ABC 369 A - 369 (6Q, 灰色, 100 点)

偶数と奇数に関する理解も問われる問題。

問題概要

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

 A, B, x を並び替えると等差数列をなす」

という条件をみたすような整数  x が何通りあるか求めよ。

制約

  •  1 \le A, B \le 100

解法 (1):数学的に解く

まず、 A, B の大小関係で場合分けして考えましょう。

  •  A \lt B の場合
  •  A = B の場合
  •  A \gt B の場合

があります。このうち、 A = B である場合は、 A, B, x が等差数列になるような  x は、 x = A = B である場合しかありません。よって、1 通りです。

また、 A \gt B である場合には、swap(A, B) をして、 A \lt B であるとしても一般性を失いません。よって、これ以降  A \lt B であるとして考えることにしましょう。

 A \lt B のとき

さて、 A \lt B であるとすると、 A, B, x が等差数列になるような  x は、整数に限らなければ、下図のように 3 通りあります。つまり、

  •  x, A, B がこの順に等差数列をなすとき
  •  A, x, B がこの順に等差数列をなすとき
  •  A, B, x がこの順に等差数列をなすとき

です。これら 3 つの場合によって求められる  x は明らかに異なる値ですので、それぞれ整数になるのかどうかのみ考えましょう。

一旦、それぞれの  x の値を求めてみましょう。

  •  x, A, B がこの順に等差数列をなすとき: x = 2A - B
  •  A, x, B がこの順に等差数列をなすとき: x = \frac{A+B}{2}
  •  A, B, x がこの順に等差数列をなすとき: x = 2B - A

となります。このうち、 2A - B 2B - A については整数になります。しかし、  \frac{A+B}{2} は整数であるとは限りません。 A+B が偶数のときは整数ですが、奇数のときは整数とはなりません。

以上をまとめると、次のように整理できます(結局  A \lt B であるか  A \gt B であるかは関係なくなります)。


  •  A = B のとき:1 通り
  • そうでなく  A + B が偶数のとき:3 通り
  • そうでないとき:2 通り

コード

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

int main() {
    int A, B;
    cin >> A >> B;

    if (A == B) cout << 1 << endl;
    else if ((A + B) % 2 == 0) cout << 3 << endl;
    else cout << 2 << endl;
}

 

解法 (2):全探索で解く

もう 1 つの方法として、 x をある範囲について全探索することが考えられます。

そこで、各  x について、 A, B, x が等差数列をなすかどうかを判定する方法を考えましょう。

 A, B, x を小さい順に並べて  p, q, r とします。このとき、 p, q, r が等間隔に並ぶかどうかを確認すればよいです。それは

 q - p = r - q であるかどうか

によって確認できます。

コード

ここでは、 x の探索範囲を -1000 から 1000 までとしています。制限時間の許す限り、範囲を大きめにとっておくのが無難でしょう。

一応最悪ケースの見積もってみましょう。

  •  A = 1, B = 100 のときに  x, A, B がこの順に等差数列をなす  x は、 x = -98 です
  •  A = 1, B = 100 のときに  A, B, x がこの順に等差数列をなす  x は、 x = 199 です

これらの  x が考えられる最小値と最大値となります。

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

int main() {
    int A, B, res = 0;
    cin >> A >> B;

    for (int x = -1000; x <= 1000; x++) {
        vector<int> v({A, B, x});
        sort(v.begin(), v.end());
        if (v[1] - v[0] == v[2] - v[1]) res++;
    }
    cout << res << endl;
}