Codeforces Round #738 (Div. 2)
阿新 • • 發佈:2021-08-16
這場真是手速場,掉分了hhhh;
A:只有1 & 1操作才會出現1,操作又可以進行無限次,那麼要出現最小值,那麼必然是要所有都進行一次。
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define pb push_back #define pi pair<int,int> #define fi first #define se second using namespace std; typedef long long ll; const ll maxn=1e5+10; #define int ll inlineint read() { char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int a[maxn]; signed main() { ios::sync_with_stdio(false); int t; cin >> t; while (t--) { int n,m; cin >> n; for (int i = 1; i<= n;i++) { cin >> a[i]; } int ans = a[1]; for (int i = 2;i <=n;i++) { ans &= a[i]; } cout<< ans << '\n'; } }
B:給你一個字串,要求相鄰出現的字元儘量不相同。
自然是形如RB相鄰最少,找到第一個非問號向兩邊拓展就可。
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define pb push_back #define pi pair<int,int> #define fi first #define se second using namespace std; typedef long long ll; const ll maxn=1e5+10; #define int ll inline int read() { char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } signed main() { ios::sync_with_stdio(false); int t; cin>>t; while(t--) { int n ; cin>>n; string s; cin>>s; int now = 0; for(int i=n-1 ; i>=0 ; i--) { if(s[i]!='?') { now = i; break; } } for(int i=now ; i<n ; ++i) { if(s[i]=='?') { if(s[i-1]=='R') s[i]='B'; else s[i]='R'; } } for(int i=now ; i>=0 ; --i) { if(s[i]=='?') { if(s[i+1]=='R') s[i]='B'; else s[i] = 'R'; } } cout<<s<<endl; } }
C:給n+1個點,n個數,0代表從i到n+1的一條有向邊,1代表從n+1到i的邊。能否從一個點開始走完全程。
3個情況,n+1有到1的邊,n有到n+1的邊,或者相鄰的0 ,1 ;
#include <bits/stdc++.h> constexpr int N = 2e5+10; using namespace std; int a[N]; int main() { int t; cin >> t; while (t--) { int n; cin >> n; for (int i = 1;i <= n;i++) cin >> a[i]; if (a[n] == 0) { for (int i = 1;i <= n+1;i++) cout << i << " "; cout << endl; } else if (a[1] == 1) { cout << n+1 << " "; for (int i = 1;i <= n;i++) cout << i << " "; cout << endl; } else { int k = -1; for (int i = 1;i <= n-1;i++) { if (a[i] == 0 && a[i+1] == 1) { k = i+1; break; } } if (k == -1) cout << -1; else for (int i = 1;i <= n;i++) { if (i == k) cout << n+1 << " " << i << " "; else cout << i << " "; } cout << endl; } } }
D1&& D2
D2 後來沒寫出來。。。
給你兩個結點相同的圖,如果能加相同的邊,並且還是森林,那麼對答案貢獻+1,問最多有幾條邊。輸出它們。
那麼思想當然是並查集。如果都滿足那麼直接加邊。
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define pb push_back #define pi pair<int,int> #define fi first #define se second using namespace std; typedef long long ll; const ll maxn=1e5+10; #define int ll inline int read() { char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } int n,m,f1[maxn]; int f2[maxn]; void init(void) { for (int i = 1;i <= n;i++) f1[i] = i,f2[i] = i; } int find1(int x) { if(f1[x]!=x) f1[x]=find1(f1[x]); return f1[x]; } int find2 (int x) { if(f2[x]!=x) f2[x]=find2(f2[x]); return f2[x]; } signed main() { ios::sync_with_stdio(false); int m1,m2; cin >> n >> m1 >> m2; init(); for (int i = 1;i <= m1;i++) { int u,v; u = read(); v = read(); if (find1(u) != find1 (v)) { f1[find1 (u)] = find1 (v) ; } } for (int i = 1;i <= m2;i++) { int u,v; u = read(); v = read(); if (find2(u) != find2 (v)) { f2[find2 (u)] = find2 (v) ; } } vector <pi> ans; for (int i = 1;i <= n;i++) { for (int j = i+1;j <=n;j++) { if ((find1(i) != find1(j)) && (find2(i) != find2(j))) { ans.push_back({i,j}); f1[find1(i)] = find1(j); f2[find2(i)] = find2(j); } } } cout<<(int)ans.size()<<'\n'; for(auto w:ans) { cout<<w.fi<<' '<<w.se<<'\n'; } }
d2對資料的範圍加大了,顯然不能遍歷所有的邊了。有一種巧妙的辦法。(見程式碼)
#include <bits/stdc++.h> #define INF 0x3f3f3f3f #define pb push_back #define pi pair<int,int> #define fi first #define se second using namespace std; typedef long long ll; const ll maxn=1e5+10; #define int ll int read() { char ch = getchar(); int x = 0, f = 1; while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = (x<<2)+(x<<3) + ch - '0'; ch = getchar(); } if(f) return x; return ~(x-1); } int n,m,f1[maxn]; int f2[maxn]; void init(void) { for (int i = 1;i <= n;i++) f1[i] = i,f2[i] = i; } int find1(int x) { if(f1[x]!=x) f1[x]=find1(f1[x]); return f1[x]; } int find2 (int x) { if(f2[x]!=x) f2[x]=find2(f2[x]); return f2[x]; } void check1(int x,int y) { if (find1(x) != find1 (y)) { f1[find1 (x)] = find1 (y); return ; } else return ; } void check2(int x,int y) { if (find2(x) != find2 (y)) { f2[find2 (x)] = find2 (y); return ; } else return ; } int vis[maxn]; bool ok1 (int x,int y) { if (find1(x) == find1(y)) return false; return true; } bool ok2 (int x,int y) { if (find2(x) == find2(y)) return false; return true; } signed main() { ios::sync_with_stdio(false); int m1,m2; cin >> n >> m1 >> m2; init(); for (int i = 1;i <= m1;i++) { int u,v; cin >> u>> v; check1 (u,v); } for (int i = 1;i <= m2;i++) { int u,v; cin >> u>> v; check2(u,v); } vector <pi> ans; for (int i = 1;i <=n;i++) { if (ok1(1,i) && ok2(1,i)) { check1(1,i); check2(1,i); ans.push_back(pi(1,i)); } } for (int i = 1;i <= n;i++) { if (ok1(1,i)) vis[find1(i)] = 1; } vector<int>v; for(int i=1;i<=n;i++) if(vis[i]) v.push_back(i); for(int i=1;i<=n;i++) if(ok2(1,i)&&!v.empty()) { int x=v.back(); if(ok1(i,x)&&ok2(i,x)) { check1(i,x);check2(i,x); ans.push_back(pi(i,x)); v.pop_back(); } } cout<<(int)ans.size()<<'\n'; for(auto w:ans) { cout<<w.fi<<' '<<w.se<<'\n'; } }