Codeforces Round #738 (Div. 2)
这场真是手速场,掉分了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 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 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'; } }

浙公网安备 33010602011771号