AtCoder Beginner Contest 140
はい. AtCoder Beginner Contest 140 です
A,B,C の3完でした. 今回はパフォーマンスもダメダメでレートも下がってしまいました…
一列に並んでいて,反転させる系の問題苦手過ぎる…
C まで20分ほどで解けているんので,やはり解く時間はあったと思います…
A - Password
なので, 1桁に 種類の記号が使えるので, するだけですね.
pow
で書いたけど,普通に n*n*n
すれば良かったですね.
#include <iostream> #include <cmath> using namespace std; int main() { int n; cin >> n; cout << pow(n,3) << endl; }
B - Buffet
問題文読み解くのに時間かかりました…
今回 C の方が簡単なのでは…?と思いました.
問題文通りに実装するだけですね.
後から気付いたんですけど, B は絶対食べるので総和取るだけで良かったですね.
for (int i=0; i<n; i++) { cin>>b; ans+=b; }
という感じですね.
#include <iostream> #include <vector> #include <algorithm> #include <cmath> using namespace std; int main() { int n; cin >> n; vector<int> a(n); vector<int> b(n); vector<int> c(n); for (int i=0; i<n; i++) cin >> a[i]; for (int i=0; i<n; i++) cin >> b[i]; for (int i=1; i<n; i++) cin >> c[i]; int ans = 0; for (int i=0; i<n; i++) { ans += b[a[i]-1]; if (i!=n-1 && a[i]+1 == a[i+1]) ans+=c[a[i]]; } cout << ans << endl; }
C - Maximal Value
という感じですね.
と に関しては, と しか制約がないのでそのまま足してあげる感じです.
#include <iostream> #include <vector> #include <utility> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <string> using namespace std; int main() { int n; cin>>n; int ans = 0; int b1,b2; cin >> b1; ans += b1; for (int i=1; i<n-1; i++) { cin >> b2; ans += min(b1,b2); b1 = b2; } ans += (n==2? b1 : b2); cout << ans << endl; }
D - Face Produces Unhappiness
しゃくとり法とかいろいろ考えていたんですが,
LR+L もしくは RL+R の場合に幸福な人が+2 されるので,LRのグループに別けて,偶数番目のグループを 回反転させるだけで良かったですね.
1度反転させて,もう1度数えるのはめんどくさいので,最初から反転させている前提で幸福な人を数えるプログラムを書きました.
#include <iostream> #include <vector> #include <utility> #include <map> #include <algorithm> #include <queue> #include <cmath> #include <string> #include <tuple> using namespace std; int main() { int n,k; int ans = 0; string s; cin >> n >> k; cin >> s; int start,i,cnt; start = i = cnt = 0; while(i<n) { char c = s[i]; while(i<n && c==s[i]) i++; cnt++; if (i<n && cnt < 2*k+1) continue; else ans += (i-start)-1; start = i; } cout << ans << endl; }
E - Second Sum
解説見ました.
全区間に対して,最大の値を解くプログラムの拡張でできるようです.
まだ実装していませんが,近いうちに実装します.
F - Many Slimes
(リャマ君と一緒に)雑にグラフを書いてたら,思いつきました.
基本的に大きい方から考えて行きます.
まず,1番大きい値と2番目に大きい値で pair を作ります(このとき 1番目>2番目).
それを queue に入れて, pair それぞれの値より小さい中で一番大きい値と pair を作って 次の queue に登録します.
これを繰り返していくと,二分木のようなものを作る事になります.
queue に追加されなくなった段階で,日付やいろいろを確認して未誕生のスライムが居たら「作れません!」という感じです.
思いついたらプログラムは難しくなかったので,コンテスト中に思いつきたかった!!
(D,E 見て難しくて F は目を通してなかった)
#include <iostream> #include <algorithm> #include <queue> #include <vector> #include <cmath> using namespace std; typedef pair<int, int> P; bool add_queue(const int s1, queue<P>& q, vector<int>& s) { auto it = lower_bound(s.begin(), s.end(), s1); if (it == s.begin()) return false; it--; q.push(P(s1, *it)); s.erase(it); return true; } int main() { int n; cin >> n; int ns = pow(2, n); vector<int> s(ns); for (int i=0; i<ns; i++) cin >> s[i]; sort(s.begin(), s.end()); int s1, s2; s2 = s.back(); s.pop_back(); s1 = s.back(); s.pop_back(); bool ans = true; queue<P> q; if (s1 < s2) q.push(P(s1, s2)); else ans = false; int day = 0; while (true) { if (q.empty()) break; queue<P> next_q; day++; while (!q.empty()) { P p = q.front(); q.pop(); s1 = p.first; s2 = p.second; add_queue(s1, next_q, s); add_queue(s2, next_q, s); } q = next_q; } ans = ans && q.empty() && s.size()<=0 && day <= n; cout << (ans?"Yes":"No") << endl; }
まとめ
今回は真面目に解いて,レート下がりました…
結構ショックでした.
コンテスト後ですが F 問題,割りと自力で解けたので良かったです.
E も近いうち解いて更新します!!