Bondo416さんのAtCoder Beginner Contest 196での成績:898位
— ボンド@競プロ (@bond_cmprog) March 20, 2021
パフォーマンス:1548相当
レーティング:1433→1445 (+12) :)#AtCoder #ABC196 https://t.co/9JEAzSq8CR
A - Difference Max
$ \mathcal{O}(1) $ でできそうだけど全探索できるのでする
提出コード
void solve(){ int a, b, c, d; cin >> a >> b >> c >> d; int ans = -INF; for(int x = a;x<=b;x++){ for(int y=c;y<=d;y++){ chmax(ans, x - y); } } cout << ans << endl; }
B - Round Down
.
が出てくるまで出力すればいい
提出コード
void solve(){ string S; cin >> S; REP(i,S.size()){ if(S[i] == '.') break; cout << S[i]; } cout << endl; }
C - Doubled
同じ文字列を連結したものを考えると6桁の文字列のとき12桁の文字列になるので $ 10^6 $ 程度まで見れば十分
今見ている値を $ i, i $ の桁数を $ cnt $ とすると $ i \times 10^{cnt} + i \leq N $ を満たしていれば答えに加算していく
提出コード
void solve(){ ll N; cin >> N; ll ans = 0; for(ll i=1;i<=1e6;i++){ ll cnt = 1; ll tmp = i; while(tmp > 0){ cnt *= 10; tmp /= 10; } ll num = i * cnt + i; if(num <= N) ans++; } cout << ans << endl; }
D - Hanjo
$ HW \leq 16 $ なのでbit全探索などで全探索ができそうなので全探索を考える
マス $ (i, j) $ の番号を $ i \times W + j $ とすると、$ (i, j) $ に $ 2 \times 1 $ の畳を縦に置く、横に置く、置かないの3通り考えられる
そのため、愚直に上記を全探索しても $ \mathcal{O}(3^{HW} HW) $ で間に合う
すでに置いてあるところに置こうとする、最下段や右端のときに縦・横に置いたりなどは出来ないので注意
提出コード
void solve(){ int H, W, A, B; cin >> H >> W >> A >> B; ll ans = 0; int n = H * W; auto dfs = [&](auto self, vector<int> &a) -> void{ if(a.size() == n){ int cnt = 0; REP(i,n) if(a[i] > 0) cnt++; if(cnt != A) return; vector<bool> used(n); REP(i,n){ if(a[i] == 0) continue; else if(a[i] == 1){ // 縦 if(i >= (H - 1) * W) return; if(used[i] or used[i+W]) return; used[i] = true; used[i+W] = true; } else{ // 横 if(i % W == W - 1) return; if(used[i] or used[i+1]) return; used[i] = true; used[i+1] = true; } } ans++; } else{ REP(i,3){ a.push_back(i); self(self, a); a.pop_back(); } } }; vector<int> a; dfs(dfs, a); cout << ans << endl; }
E - Filters
beatsで殴れる
関数を合成していくと、最終的には解説の図のようになる
最終的にある下限 $ mi $ 以下はすべて $ mi, $ ある上限 $ ma $ 以上はすべて $ ma, $ それ以外の場合 $ x ( mi \lt x \lt ma ) $ となる
そのため、$ f(-INF), f(INF) $ の値を実際に求めておき、$ t_i = 1 $ で加算される総和を $ sum $ として求めておくと各クエリの答えはclamp(x+sum, f(-INF), f(INF)
として求められる
提出コード
void solve(){ int N; cin >> N; ll mi = -LINF; ll ma = LINF; ll sum = 0; REP(i,N){ ll a, t; cin >> a >> t; if(t == 1){ sum += a; mi += a; ma += a; } else if(t == 2){ chmax(ma, a); chmax(mi, a); } else{ chmin(ma, a); chmin(mi, a); } } int Q; cin >> Q; while(Q--){ ll x; cin >> x; cout << clamp(x + sum, mi, ma) << endl; } }