C++の練習を兼ねて, AtCoder Regular Contest 134 の 問題A (Bridge and Sheets) ~ 問題B (Reserve or Reverse) を解いてみた.
■感想.
1. 問題Bは, 方針が見えなかったので, 解説を参考に実装して, AC版に到達出来た.
2. 問題Bは, 実装に苦労したものの, 個人的には, 解説にあるロジックで, 辞書順最小の文字列を抽出できることが, 非常に興味深く思った.
3. 引き続き, 時間を見つけて, 過去問の学習を進めていきたいと思う.
本家のサイト AtCoder Regular Contest 134 解説 の 各リンク を ご覧下さい.
■C++版プログラム(問題A/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 |
// 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 L, W; scanf("%d %lld %lld", &N, &L, &W); rep(i, N) scanf("%lld", &a[i]); a[N] = L; // 2. シートの枚数は? LL ans = 0, cur = 0; rep(i, N + 1){ // 現在位置が, 設置位置より左側にあるケース. if(cur < a[i]){ LL q = (a[i] - cur) / W; LL r = (a[i] - cur) % W; ans += q + (r > 0); cur += (q + (r > 0)) * W; cur = max(cur, a[i] + W); continue; } // 現在位置が, 設置位置より右側にあるケース. if(cur >= a[i]) cur = max(cur, a[i] + W); } // 3. 出力. 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 |
[入力例] 2 10 3 3 5 [出力例] 2 ※AtCoderのテストケースより [入力例] 5 10 3 0 1 4 6 7 [出力例] 0 ※AtCoderのテストケースより [入力例] 12 1000000000 5 18501490 45193578 51176297 126259763 132941437 180230259 401450156 585843095 614520250 622477699 657221699 896711402 [出力例] 199999992 ※AtCoderのテストケースより [入力例] 5 40 5 11 17 18 25 35 [出力例] 6 [入力例] 15 111 7 5 11 23 25 33 40 52 58 70 78 86 87 91 101 108 [出力例] 8 |
■C++版プログラム(問題B/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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
// 解き直し. // https://atcoder.jp/contests/arc134/editorial/3326 // C++(GCC 9.2.1) #include <bits/stdc++.h> using namespace std; #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--) int sCum[202020][26]; int main(){ // 1. 入力情報. int N; char c[202020]; scanf("%d %s", &N, c); string s(c); // 2. 累積和. repx(i, 1, N + 1){ ++sCum[i][s[i - 1] - 'a']; rep(j, 26) sCum[i][j] += sCum[i - 1][j]; } /* rep(i, N + 1){ rep(j, 26) printf("%d ", sCum[i][j]); puts(""); } */ // 3. 貪欲法. int q = N - 1; rep(p, N){ // 終了条件. if(q <= p) break; // p文字目. int cur = s[p] - 'a'; // p文字目より最も右側で, 最小となる文字があるか? int m = -1; rep(j, cur){ if(sCum[q + 1][j] - sCum[p + 1][j] > 0){ m = j; break; } } // 次へ. if(m == -1) continue; // 最小の文字を探す. int at = q + 1; repr(j, q, p + 1){ if(m == s[j] - 'a'){ at = j; break; } } // 次へ. if(at == q + 1) continue; // q を 更新し, スワップ. q = at; swap(s[p], s[q]); // デクリメント. --q; } // 4. 出力. printf("%s\n", s.c_str()); 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
[入力例] 4 dcab [出力例] acdb ※AtCoderのテストケースより [入力例] 2 ab [出力例] ab ※AtCoderのテストケースより [入力例] 16 cabaaabbbabcbaba [出力例] aaaaaaabbbbcbbbc ※AtCoderのテストケースより [入力例] 17 snwfpfwipeusiwkzo [出力例] effwpnwipsusiwkzo ※AtCoderのテストケースより [入力例] 11 abracadabra [出力例] aaaaacdrbrb [入力例] 50 ubjclqgsqnnudgnfwfisikuqcdcmybvkwdomjbpocumfjngqid [出力例] bbbcccdnnqsuggnfwfisikuqqdlmyjvkwdomjupocumfjngqid [入力例] 100 huswufokysasxnrhpwweddrnmylmnzpmkbyuublhnmujpsrexqpedbhiixcsavgbsejichvoywvpjgyvcxtqopdvibcarjqecacp [出力例] aaaafuokyswsxnrhpwweddrnmylmnzpmkbyuublhnmujpsrexqpedbhiixcssvgbsejichvoywvpjgyvcxtqopdvibcurjqechcp [入力例] 200 illytageazvxvvoiaboenviyjwvuknebmhsrovungfmnokumfrfwxruqwurwpgraocrerihmeotxmimbqaztonpanphijkbxyloxlkjgftaafqiuhbuytlfprvhzokuvwfaqbeioepgusidicsbswdicapnvusytkytmznytbykwinzslruwpsgmedyzjjiefufmkohj [出力例] aaaaaaaaaaiovvxvzboenviyjwvuknebmhsrovungfmnokumfrfwxruqwurwpgreocrerihmeotxmimbqgztonptnphijkbxyloxlkjgftylfqiuhbuytlfprvhzokuvwflqbeioepgusidicsbswdicipnvusytkytmznytbykwinzslruwpsgmedyzjjiefufmkohj [入力例] 500 mwdhquqkdffqifgnzsdfmbvduibxldjttgvezqejsslmcflwvdlkmcweiocuoahtlepjkxpiidsrilcvrunvbvrdtkzazbemysumysirvztrojokdkoevtuixeihianwnhrczfpvsfsdlphxvblirgkjipkrdvrprbkdjhijzwgfzwmgiqaodlukkixszbrurdfviwgvsgwkayfsitbzvszurzvsupuerqdwjejkohkrolhfgygybwtqrufhiyeodeaijlomynekfgvfydpbivdioydjjpvqeqvlxgrrqanpewlvpulpdaharhxtiywdvpdkqjkkbefwiobnmvijusfscpzssrkiumerprhqbgbpvugvmvtudrjmfrwqozmhcxhlyadeztkafdpyvwitnyuynideaubnbstzlmhthsorlzyuqstgdoskpvvpglvasuyldsohqgeetqnpsloryothuigwugtsrohfxhndxoekqfcencvq [出力例] aaaaaaaaaaaaabbdsznfmgvduifxldjttgvezqejsslmcflwvdlkmcweiocuoihtlepjkxpiidsrilcvrunvbvrdtkzqzbemysumysirvztrojokdkoevtuixeihifnwnhrczfpvsfsdlphxvblirgkjipkrdvrprbkdjhijzwgfzwmgiqfodlukkixszbrurdfviwgvsgwkdyfsitbzvszurzvsupuerqdwjejkohkrolhfgygybwtqrufhiyeodekijlomynekfgvfydpbivdioydjjpvqeqvlxgrrqqnpewlvpulpduhqrhxtiywdvpdkqjkkbefwiobnmvijusfscpzssrkiumerprhqbgbpvugvmvtudrjmfrwqozmhcxhlyhdeztkdfdpyvwitnyuynidewubnbstzlmhthsorlzyuqstgdoskpvvpglvmsuyldsohqgeetqnpsloryothuigwugtsrohfxhndxoekqfcencvq |
■参照サイト
AtCoder Regular Contest 134