【C++】ABC265 D問題 Iroha and Haiku

未分類

ABC265のD問題 Iroha and Haikuを解説します。

問題を理解する
最初にこの問題を見た時に、ぱっと問題を理解できませんでした。
いくつか例を試してようやく理解できました。例示は理解の試金石です。
以下のような例を複数考えました。

問題のポイント
累積和という考え方です。
その名の通り、和を”積んで”いきます。
例えば、1 3 2 2というような数列の累積和を考えると、1 4 6 8となります。
(今回の問題では、最初は0となるようにしています。)
以下のような形で、累積和のvectorを作成しています。

入力例

10 5 7 5
1 3 2 2 2 3 1 4 3 2

回答例

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < (n); ++i)

int main() {
    int n;
    ll p, q, r;
    cin >> n >> p >> q >> r;
    vector<int> a(n);
    rep(i, n) cin >> a[i];

    vector<ll> s(n+1);  // vector a の累積和のvectorを準備。0スタートのため、サイズはn+1
    s[0] = 0;
    for (int i = 1; i <= n; i++) {  // 累積和を作成
        s[i] = s[i-1] +a[i-1];
    }

    set<ll> st;
    rep(i, n+1) st.insert(s[i]);    // 累積和で得られた値を全てstに入れる

    // 累積和のある地点から見て、差がp、q、rとなっているものがstにあるかを調べている
    // その「ある地点」というのをfor文で回して色々試している。    
    rep(i, n+1) {
        ll start = s[i];
        if (st.count(start + p) > 0 && st.count(start + p + q) > 0 && st.count(start + p + q + r) > 0) {
            cout << "Yes" << endl;  // 差がp、q、r全てを満たしている場合"Yes"を出力
            return 0;
        }
    }

    cout << "No" << endl;   // 全てを試してなかったのであれば、"No"を出力
    return 0;
}

コメント