《NEC Programming Contest 2021(AtCoder Beginner Contest 229)》
阿新 • • 發佈:2021-11-28
A:簽到
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 5; const int M = 1e6 + 5; const LL Mod = 1e9 + 7; #define INF 1e9 #define IN_INF 0x3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; void solve() {View Codestring s1,s2; cin >> s1 >> s2; int cnt = 0,f1 = 0,f2 = 0; for(int i = 0;i < 2;++i) { if(i == 0) { if(s1[i] == '#') { cnt++; if(s1[1] != '#' && s2[0] != '#') f1 = 1; } if(s2[i] == '#') { cnt++; if(s2[1] != '#' && s2[0] != '#') f1 = 1; } } else { if(s1[i] == '#') { cnt++; if(s1[0] != '#' && s2[1] != '#') f1 = 1; } if(s2[i] == '#') { cnt++;if(s2[0] != '#' && s2[1] != '#') f1 = 1; } } } if(cnt <= 1) printf("Yes\n"); else { printf("%s\n",f1 ? "No" : "Yes"); } } int main() { solve(); // system("pause"); return 0; }
B:簽到
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 5; const int M = 1e6 + 5; const LL Mod = 1e9 + 7; #define INF 1e9 #define IN_INF 0x3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; void solve() { string s1,s2; cin >> s1 >> s2; reverse(s1.begin(),s1.end()); reverse(s2.begin(),s2.end()); int mi = min(s1.size(),s2.size()),f = 0; for(int i = 0;i < mi;++i) { int ad = s1[i] - '0' + s2[i] - '0'; if(ad >= 10) f = 1; } printf("%s\n",f ? "Hard" : "Easy"); } int main() { solve(); // system("pause"); return 0; }View Code
C:簽到
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 5; const int M = 1e6 + 5; const LL Mod = 1e9 + 7; #define INF 1e9 #define IN_INF 0x3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; struct Node{int a,b;}p[M]; bool cmp(Node a,Node b) {return a.a > b.a;} void solve() { int n,w;scanf("%d %d",&n,&w); for(int i = 1;i <= n;++i) scanf("%d %d",&p[i].a,&p[i].b); sort(p + 1,p + n + 1,cmp); LL ans = 0; for(int i = 1;i <= n;++i) { if(w >= p[i].b) { ans += 1LL * p[i].b * p[i].a; w -= p[i].b; } else { ans += 1LL * w * p[i].a; break; } } printf("%lld\n",ans); } int main() { solve(); // system("pause"); return 0; }View Code
D:可以發現這裡左右移動都是差不多的。
所以我們可以欽定一個左端點,然後去檢查能得到的最大右端點。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 5; const int M = 1e6 + 5; const LL Mod = 1e9 + 7; #define INF 1e9 #define IN_INF 0x3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; vector<int> vec; int d[N],val[N],cnt[N],mx[N]; void solve() { string s; int k; cin >> s >> k; int n = s.size(); // int tot1 = 0,len2 = 0; // for(int i = 0;i < s.size();++i) { // if((i == 0 || s[i - 1] == '.') && s[i] == 'X') { // if(tot1 == 0) len2 = 0; // d[++tot1] = len2; // val[tot1] = 1; // len2 = 0; // } // else if(s[i] == 'X') { // val[tot1]++; // } // else ++len2; // } for(int i = 1;i <= n;++i) { cnt[i] = cnt[i - 1]; if(s[i - 1] == '.') cnt[i]++; mx[cnt[i]] = i; } int ans = 0; for(int i = 1;i <= n;++i) { int r = cnt[i - 1] + k; int ss = cnt[n] - cnt[i - 1]; if(k >= ss) ans = max(ans,n - i + 1); else { ans = max(ans,mx[r] - i + 1); } // dbg(ans); } printf("%d\n",ans); } int main() { solve(); //system("pause"); return 0; }View Code
E:倒著並查集維護即可
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 5; const int M = 1e6 + 5; const LL Mod = 1e9 + 7; #define INF 1e9 #define IN_INF 0x3f3f3f #define dbg(ax) cout << "now this num is " << ax << endl; struct Node{int L,r;}p[M]; int fa[N]; int Find(int x) {return x == fa[x] ? x : fa[x] = Find(fa[x]);} vector<int> G[N],tmp; void solve() { int n,m;scanf("%d %d",&n,&m); for(int i = 1;i <= m;++i) { scanf("%d %d",&p[i].L,&p[i].r); G[min(p[i].L,p[i].r)].push_back(max(p[i].L,p[i].r)); } int ans = 0; for(int i = 1;i <= n;++i) fa[i] = i; for(int i = n;i >= 1;--i) { tmp.push_back(ans); for(auto v : G[i]) { int x = Find(v),y = Find(i); if(x != y) { ans--; fa[x] = y; } } ans++; } reverse(tmp.begin(),tmp.end()); for(auto v : tmp) printf("%d\n",v); } int main() { solve(); //system("pause"); return 0; }View Code
F:題意沒讀懂,好像是個不太難的染色dp
G:考慮對於每一個Y,令第i個Y的B[i]表示pos[i] - i.
每次操作就等價於每次對B[i],+1或者-1
那麼對於一段連續的Y,如果要讓他們連在一起,就是讓一段B都相等。
很顯然這裡可以得出B[i] - B[i -1] >= 0。也就表示B是一個遞增序列。
考慮一個序列{a1,a2,....an}要讓所以的數到一個數的差值和的絕對值最小,顯然那個目標數應該是中位數。
那麼這個總共需要的步數也就是$\sum_{i = L}^{r} |b[i] - mid|$
所以我們可以列舉一個左端點,然後二分長度,中間的判斷可以用字首和優化(因為B肯定遞增)。
// Author: levil #include<bits/stdc++.h> using namespace std; typedef long long LL; typedef long double ld; typedef pair<int,int> pii; const int N = 2e5 + 5; const int M = 5e6 + 5; const LL Mod = 1e9 + 7; #define INF 1e9 #define dbg(ax) cout << "now this num is " << ax << endl; inline long long ADD(long long x,long long y) { if(x + y < 0) return ((x + y) % Mod + Mod) % Mod; return (x + y) % Mod; } inline long long MUL(long long x,long long y) { if(x * y < 0) return ((x * y) % Mod + Mod) % Mod; return x * y % Mod; } inline long long DEC(long long x,long long y) { if(x - y < 0) return (x - y + Mod) % Mod; return (x - y) % Mod; } string s; LL k,pre[N]; int b[N],n; bool check(int L,int len) { int r = L + len - 1; int mid = L + len / 2; LL ma = pre[r] - pre[mid] - 1LL * (r - mid) * b[mid]; ma += 1LL * (mid - L) * b[mid] - (pre[mid - 1] - pre[L - 1]); if(ma <= k) return true; else return false; } void solve() { cin >> s >> k; n = s.size(); int tot = 0; for(int i = 1;i <= n;++i) { if(s[i - 1] == 'Y') { ++tot; b[tot] = i - tot; } } int ans = 0; for(int i = 1;i <= tot;++i) pre[i] = pre[i - 1] + b[i]; for(int i = 1;i <= tot;++i) { int L = 1,r = tot - i + 1; while(L <= r) { int mid = (L + r) >> 1; if(check(i,mid)) { ans = max(ans,mid); L = mid + 1; } else r = mid - 1; } } printf("%d\n",ans); } int main() { //int _; //for(scanf("%d",&_);_;_--) solve(); system("pause"); return 0; }View Code