接着剤の精進日記

競プロでの精進や研究に関係したことを書いていきます。

鹿島建設プログラミングコンテスト2020(AtCoder Regular Contest 110)

atcoder.jp

A - Redundant Redundancy

$ 2, 3, ..., N $のLCMは$2, 3, ..., N $の倍数になるのでこれに1を加えたものが条件を満たす
提出コード

void solve(){
    ll n;
    cin >> n;
    ll ans = 1;
    for(int i=1;i<=n;i++) ans = lcm(ans, i);
    cout << ans + 1 << endl;
}

B - Many 110

Tの先頭が110のどこから始まるかで場合分けをする
$ |T| \leq 2 $のときは答えを場合分けしておく
$ |T| \geq 3 $のときは先頭3文字だけを場合分けする
このとき、一番初めに条件を満たす連続する部分文字列の末尾のindexを求めると答えは$ 10^{10} - \frac{index-1}{3} $ 提出コード

void solve(){
    ll N;
    string T;
    cin >> N >> T;
    if(T == "1") cout << (ll)1e10 * 2 << endl;
    else if(T == "0") cout << (ll)1e10 << endl;
    else if(T == "10") cout << (ll)1e10 << endl;
    else if(T == "01") cout << (ll)1e10 - 1 << endl;
    else if(T == "11") cout << (ll)1e10 << endl;
    else{
        bool ok = true;
        int index = (int)T.size();
        if(T.substr(0,3) == "110"){
            string s = "110";
            for(int i=3;i<T.size();i++) if(T[i] != s[i%3]) ok = false;
        }
        else if(T.substr(0,3) == "101"){
            string s = "101";
            index++;
            for(int i=3;i<T.size();i++) if(T[i] != s[i%3]) ok = false;
        }
        else if(T.substr(0,3) == "011"){
            string s = "011";
            index += 2;
            for(int i=3;i<T.size();i++) if(T[i] != s[i%3]) ok = false;
        }
        else ok = false;

        if(!ok){
            cout << 0 << endl;
            return;
        }
        cout << (ll)1e10 - (index - 1) / 3 << endl;
    }
}

C - Exoswap

$ 1, 2, ..., N-1 $の順に$ P_i = i $となるようにソートをしていく
途中ですでに行った操作が必要になる場合は-1
また、操作を行った回数が$ N - 1 $にならない場合も-1
それ以外の場合は上記の操作を行うことで答えが求められる
提出コード

void solve(){
    int n;
    cin >> n;
    vector<int> a(n), b(n);
    REP(i,n){
        cin >> a[i];
        a[i]--;
    }

    vector<int> idx(n);
    REP(i,n) idx[a[i]] = i;
    vector<bool> used(n);
    vector<int> ans;
    for(int i=0;i<n;i++){
        if(idx[i] > i){
            for(int j=idx[i];j>i;j--){
                if(used[j]){
                    cout << -1 << endl;
                    return;
                }
                ans.emplace_back(j);
                used[j] = true;
                swap(idx[a[j]], idx[a[j-1]]);
                swap(a[j], a[j-1]);
            }
        }
    }
    if(ans.size() != n-1) cout << -1 << endl;
    else for(auto x : ans) cout << x << endl;
}