【競プロ】1日1AC : ABC133 C問題

最近サボっていましたが、やる気が出たので更新します。
今日の問題はこちら。

Diffは557(茶)です。
是非先に解いてから読み進めてください。

提出コードと考え方

制約上、\(i,j\) を全通り試すのは不可能です。あまりについて考えているので、それを利用しましょう。以下、合同式は \(\mod 2019\) とします。

\(i=L+di,j=R-dj\) のように表せますが、\(L\equiv l,R\equiv r\) とすると \(i\equiv l+di,j=r-dj\)となります。\(l<r\) であれば、これは単に区間 \([L,R]\) が\([l,r]\) に縮小されたと考えることができます。
区間の長さは高々 \(2019\) ですから、この範囲(\(l\leq i<j\leq r\))で全ての値を調べることで求めるべき最小値が見つかります。
\(l\geq r\) の場合でも、この間に属する \(i,j\) について計算を行なっていいことが確認できるでしょう。

ただし、\([L,R]\) の長さが \(2019\) 以上になる場合は \(i\equiv 0\) となるように \(i\) を選べるので例外的に処理します。以下が提出コードです。

#include <iostream>
using namespace std;

int main(){
    int L,R;
    cin >> L >> R;

    if(L+2019 <= R){
        cout << 0 << endl;
        return 0;
    }

    int mL = L%2019, mR = R%2019;
    if(mL > mR) swap(mL,mR);
    int ans = 2020;
    for(int i = mL;i < mR;i++){
        for(int j = i+1;j <= mR;j++){
            ans = min(ans,i*j % 2019);
        }
    }
    cout << ans << endl;
    return 0;
}

終わりに

やや解き方が違うので、公式の解説提出コード)も覗いてみてください。

コメント