C++の練習を兼ねて, AtCoder Beginner Contest 150 の 問題D (Semi Common Multiple) を解いてみた.
■感想.
1. 問題Dは, 方針が見えなかったので, 解説を参考に, AC版に到達できたと思う.
2. 引き続き, 時間を見つけて, 過去問の学習を進めていきたいと思う.
本家のサイト AtCoder Beginner Contest 150 解説 を ご覧下さい.
■C++版プログラム(問題D/AC版).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
// 解き直し. // https://img.atcoder.jp/abc150/editorial.pdf // C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; using LL = long long; #define repex(i, a, b, c) for(int i = a; i < b; i += c) #define repx(i, a, b) repex(i, a, b, 1) #define rep(i, n) repx(i, 0, n) #define repr(i, a, b) for(int i = a; i >= b; i--) LL a[101010]; int main(){ // 1. 入力情報. int N; LL M; scanf("%d %lld", &N, &M); rep(i, N) scanf("%lld", &a[i]); // 2. 2 で 割り切れる回数. set<int> st; rep(i, N){ LL b = a[i]; int x = 0; while(!(b & 1)){ b >>= 1; ++x; } st.insert(x); } // 3. 例外. if(st.size() > 1){ puts("0"); return 0; } // 4. 最小公倍数. LL lcm = a[0] / 2; repx(i, 1, N){ LL g = __gcd(lcm, a[i] / 2); lcm /= g; lcm *= (a[i] / 2); } // 5. 集計(85.txt で WA版となったので, ロジック修正). M += (lcm - M % lcm); LL ans = M / lcm / 2; // 6. 出力. printf("%lld\n", ans); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
[入力例] 2 50 6 10 [出力例] 2 ※AtCoderテストケースより [入力例] 3 100 14 22 40 [出力例] 0 ※AtCoderテストケースより [入力例] 5 1000000000 6 6 2 6 2 [出力例] 166666667 ※AtCoderテストケースより [入力例] 5 987654321 70 210 350 490 630 [出力例] 44792 [入力例] 10 1000000000 14 70 70 98 98 126 154 154 178 178 [出力例] 232 [入力例] 7 20200110 40 56 104 24 88 136 168 [出力例] 10 [入力例] 12 20220408 24 24 40 56 40 24 24 104 56 136 56 40 [出力例] 109 |
■参照サイト
AtCoder Beginner Contest 150