KYOCERA Programming Contest 2022(AtCoder Beginner Contest 271) - AtCoder
B - Maintain Multiple Sequences
- 隣接リストで持つ
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) #define endl '\n' int main() { int n,q; cin >> n >> q; vector<vector<int>> g(n); REP(i,n) { int l; cin >> l; REP(j,l) { int x; cin >> x; g[i].push_back(x); } } REP(i,q) { int s,t; cin >> s >> t; s--; t--; cout << g[s][t] << endl; } return 0; }
C - Manga
- シミュレーションで解けるが実装がごちゃつく
- こちらの 解説 のように二分探索を使うと楽だった
[シミュレーション解]
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) #define endl '\n' int main() { int n; cin >> n; vector<int> a(n); set<int> st; REP(i,n) { cin >> a[i]; st.insert(a[i]); } int dup = n - st.size(); vector<int> b; for(int v: st) b.push_back(v); int ans = 0, now = 0; int bsz = b.size(); for(int i = 1; i <= n; i++) { if (now < bsz && b[now] == i) { now++; } else { int need = 2; need -= min(2,dup); dup -= min(2,dup); bsz -= need; if (now > bsz) break; } ans++; } ans += dup/2; cout << ans << endl; return 0; }
[二分探索解]
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) #define endl '\n' int main() { int n; cin >> n; vector<int> a(n); set<int> st; REP(i,n) { cin >> a[i]; st.insert(a[i]); } int ok = 0, ng = n+1; while(abs(ok-ng) > 1) { int mid = (ok+ng)/2; // mid巻まで読めるかどうか int sell = n - st.size(); sell += distance(st.upper_bound(mid), st.end()); for(int i = 1; i <= mid; i++) { if (st.count(i) == 0) sell -= 2; } if (sell >= 0) ok = mid; else ng = mid; } cout << ok << endl; return 0; }
D - Flip and Adjust
- DP経路復元
#include <bits/stdc++.h> using namespace std; #define REP(i,n) for(int i=0;i<(n);i++) #define endl '\n' vector<int> a(100),b(100); vector dp(101, vector<bool>(10001)); string ans; void dfs(int i, int now, string str) { if (ans.size()) return; if (i == 0) { if (now == 0) ans = str; return; } int na = now - a[i-1]; int nb = now - b[i-1]; if (na >= 0 && dp[i-1][na]) dfs(i-1, na, "H" + str); if (nb >= 0 && dp[i-1][nb]) dfs(i-1, nb, "T" + str); return; } int main() { int n,s; cin >> n >> s; REP(i,n) cin >> a[i] >> b[i]; dp[0][0] = true; REP(i,n) REP(j,s+1) { if (j - a[i] >= 0) dp[i+1][j] = dp[i+1][j] || dp[i][j - a[i]]; if (j - b[i] >= 0) dp[i+1][j] = dp[i+1][j] || dp[i][j - b[i]]; } if (dp[n][s]) { cout << "Yes" << endl; dfs(n, s, ""); // 経路復元 cout << ans << endl; } else { cout << "No" << endl; } return 0; }