接着剤の精進日記

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

AtCoder Beginner Contest 149 (ABC149)

今年最後のABC!
unratedになっちゃったね(悲しいね)

A - Strings

注意力?
TとSの順に出力
提出コード

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    string S, T;
    cin >> S >> T;
    cout << T << S << endl;
}

B - Greedy Takahashi

AからKを引いて(Kが大きかったら0まで)
Kが残ってたらBから残りのKを引く
提出コード

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll A ,B, K;
    cin >> A >> B >> K;
    ll tmp = A - K;
    if(tmp > 0){
        cout << tmp << " " << B << endl;
    }
    else{
        K -= A;
        B = max(0LL, B - K);
        cout << 0 << " " << B << endl;
    }
}

C - Next Prime

制約から、最大の素数が1e5+3なのでXからこれくらいまで素数判定していく
最初に素数だったものを出力
提出コード

bool is_prime(int n){
    for(int i = 2;i * i <=n;i++){
        if(n % i == 0) return false;
    }
    return n != 1; //1の場合は例外
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll X;
    cin >> X;

    for(ll i=X;i<=INF;i++){
        if(is_prime(i)){
            cout << i << endl;
            return 0;
        }
    }
}

D - Prediction and Restriction

見た瞬間DはDPのD!と言いながら無限にバグらせてた(は?)
ぐっと睨むとmod Kが同一のところしか見る必要がなくて、今見ているところと、次に見るところで相手が出す手が同じだった場合、今見ているところを取っちゃったほうがいい
今見ているところで勝つ手を出しても、次の手ではその次の次に勝てるような手を選べるのでこちらのほうがお得
なので貪欲法で前から見ていけばいい
mod KでDPのほうがいい気がするけど貪欲で書いちゃった
提出コード

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll N, K, R, S, P;
    string T;
    cin >> N >> K >> R >> S >> P >> T;
    ll ans = 0;
    char pre = '!';
    REP(j,K){
        char pre = '!';
        for(int i=j;i<N;i+=K){
            if(pre == '!'){
                if(T[i] == 'r'){
                    ans += P;
                    pre = 'r';
                }
                else if(T[i] == 's'){
                    ans += R;
                    pre = 's';
                }
                else if(T[i] == 'p'){
                    ans += S;
                    pre = 'p';
                }
            }
            else{
                if(pre == T[i]){
                    pre = '!';
                    continue;
                }
                if(T[i] == 'r'){
                    ans += P;
                    pre = 'r';
                }
                else if(T[i] == 's'){
                    ans += R;
                    pre = 's';
                }
                else if(T[i] == 'p'){
                    ans += S;
                    pre = 'p';
                }
            }
        }
    }
    cout << ans << endl;
}

E - Double Factorial

これ難しくない?
幸福度の上がる値が大きいものがからM個取ればいい
全列挙したくなるけど制約的に無理で、どれくらいペアが使えるかを考えると累積和を上手く使うと求められる
あとは、にぶたんを上手く使って握手の方法がM以上になる最小の値を求めれば出来るっぽい
まだ実装してないので、後でちゃんとやっておきます

おわりに

unratedは悲しいけど、ratedだったら冷えてるのも悲しいね
こどふぉのGood Bye 2019出るよ