接着剤の精進日記

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

AtCoder Beginner Contest 150 (ABC150)

2連続でunratedになっちゃったね(悲しいね)
色々言われてるけどコンテストがこれからもあればいいかなあというお気持ち
clarの今の仕様は本当に気づけ無いのでそこだけはこどふぉみたいにわかりやすくしてくれないかなあという感じ

A - 500 Yen Coins

500をかけて確かめる
提出コード

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll K, X;
    cin >> K >> X;
    if(X <= 500*K) cout << "Yes" << endl;
    else cout << "No" << endl;
}

B - Count ABC

愚直にABCを全部数えれば良い
substrたまにバグらせるのでちょっとビクビクしながらコード投げた
提出コード

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    string S;
    cin >> N >> S;
    string X = "ABC";
    int ans = 0;
    REP(i,N-2){
        if(S.substr(i,3) == X) ans++;
    }
    cout << ans << endl;
}

C - Count Order

脳死next_permutation
最近出たイメージだからまた出てきてちょっとびっくり
全列挙して数列が一致した時の辞書順を記憶する
本番中今が何番目か数えて無くて答えが全部0になって切れてました(は?)
提出コード

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    vector<int> P(N), Q(N), idx(N);
    REP(i,N) cin >> P[i];
    REP(i,N) cin >> Q[i];
    iota(idx.begin(), idx.end(), 1);
    int a = -1, b = -1;
    int cnt = 1;
    do{
        bool okp = true;
        bool okq = true;
        REP(i,N){
            if(P[i] != idx[i]){
                okp = false;
                break;
            }
        }
        REP(i,N){
            if(Q[i] != idx[i]){
                okq = false;
                break;
            }
        }
        if(okp){
            a = cnt;
        }
        if(okq){
            b = cnt;
        }
        cnt++;
    }while(next_permutation(idx.begin(), idx.end()));
    cout << abs(a-b) << endl;
}

D - Semi Common Multiple

これ難しくない?本番中解けず
まず数式を変形させることを考える
a_kは全部偶数なのでX = a_k' (2p + 1) ,( a_k = 2a_k'
これは、数列全体の最小公倍数を求めて奇数倍の個数を数えてあげれば良さそう、WA(本番終了)
ここで、Xa_k'の奇数倍なので
Xa_k'の倍数かつ各a_k'が持つ2の素因数の個数が一致する必要がある
あとは、LCMがMを超えたらその時点で答えは存在しないので0で打ち切る
それ以外で答えが存在するときは、\frac{M}{LCM}でM以下のLCMの倍数の個数が求められる
ただし、条件を満たすものはLCMの奇数倍なので、\frac{\frac{M}{LCM}+1}{2}が答え
やっぱり難しい...
提出コード

ll lcm( ll m, ll n ){
    if ( ( 0 == m ) || ( 0 == n ) ) return 0;
    return ((m / gcd(m, n)) * n);// lcm = m * n / gcd(m,n)
}


int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    ll N, M;
    cin >> N >> M;
    vector<ll> a(N);
    set<int> pf;
    ll L = 1;
    REP(i,N){
        cin >> a[i];
        a[i] /= 2;
        L = lcm(L, a[i]);
        int cnt = 0;
        while(a[i] % 2 == 0){
            cnt++;
            a[i] /= 2;
        }
        pf.insert(cnt);
        if(L > M){
            cout << 0 << endl;
            return 0;
        }
    }
    if(pf.size() > 1){
        cout << 0 << endl;
        return 0;
    }
    cout << (M / L + 1) / 2 << endl;
}

おわりに

unratedは悲しいね
その後のこどふぉは割と温まったのでAtCoderも温まりたい
Dは式変形して考えるのは良かったけど素因数の個数の一致が全然見えてなかったので満たす必要のある条件を挙げれるようにしないとなあという感じ
EもFも全然見てないのでちゃんとやらないと