Codeforces Round #544 题解
A题
用scanf读入更加方便,之后只要计算差值即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef map<string,int> st; const int N=5e5+10; int main(){ //ios::sync_with_stdio(false); int h1,m1,h2,m2; scanf("%02d:%02d",&h1,&m1); scanf("%02d:%02d",&h2,&m2); int x=h2-h1; int y=m2-m1; x=x*60+y; x/=2; int d1=x/60; int d2=x%60; printf("%02d:%02d",h1+d1+((m1+d2)/60),(m1+d2)%60); }
B题
用一个桶来维护答案,取min求和即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef map<string,int> st; const int N=5e5+10; int a[N]; int cnt[N]; int main(){ ios::sync_with_stdio(false); int n,k; cin>>n>>k; int i; for(i=1;i<=n;i++){ cin>>a[i]; a[i]%=k; cnt[a[i]]++; } int ans=0; ans+=cnt[0]/2; for(i=1;i<=k/2;i++){ if(i!=k-i) ans+=min(cnt[i],cnt[k-i]); else{ ans+=cnt[i]/2; } } cout<<ans*2<<endl; }
C题
经典套路,枚举每个位置之后二分求当前位置的最大答案后取max
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef map<string,int> st; const int N=5e5+10; vector<int> num; int find(int x){ return lower_bound(num.begin(),num.end(),x+6)-num.begin(); } int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i; for(i=1;i<=n;i++){ int x; cin>>x; num.push_back(x); } sort(num.begin(),num.end()); int ans=0; for(i=0;i<(num).size();i++){ int x=num[i]; int pos=find(x)-1; ans=max(ans,pos-i+1); } cout<<ans<<endl; }
D题
用map+pair维护答案,只要求取最大的即可,这里要注意0的情况
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; typedef map<string,int> st; const int N=5e5+10; map<pll,int> m1; int c[N],d[N]; int gcd(int a,int b){ return b?gcd(b,a%b):a; } int main(){ ios::sync_with_stdio(false); int n; cin>>n; int sum=0; for(int i=1;i<=n;i++) cin>>c[i]; for(int i=1;i<=n;i++) cin>>d[i]; for(int i=1;i<=n;i++){ ll a,b; a=c[i]; b=d[i]; int sign=0; if(a<0){ sign^=1; a=-a; } if(b<0){ sign^=1; b=-b; } if(a==0){ sum+=(b==0); continue; } if(b==0){ m1[{0,0}]++; } int d=gcd(a,b); a/=d; b/=d; if(sign==0){ sign=1; } else{ sign=-1; } m1[{sign*b,a}]++; } int mx=0; for(auto tmp:m1){ mx=max(mx,tmp.second); } mx+=sum; cout<<mx<<endl; }
E题
考虑使用dp,数据范围也暗示了这一点,每个位置只有取和不取,不取直接由前面信息更新,而取一定是取最远的,所以二分求最远距离更新即可
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; int a[N]; int f[5050][5050]; int main(){ ios::sync_with_stdio(false); int n,k; cin>>n>>k; int i,j; for(i=1;i<=n;i++){ cin>>a[i]; } sort(a+1,a+1+n); a[0]=-0x3f3f3f3f; for(i=1;i<=n;i++){ for(j=1;j<=k&&j<=i;j++){ int l=0,r=i; while(l<r){ int mid=l+r>>1; if(abs(a[i]-a[mid])<=5) r=mid; else l=mid+1; } f[i][j]=max(f[i-1][j],f[l-1][j-1]+(i-l+1)); } } int ans=0; for(i=1;i<=k;i++) ans=max(ans,f[n][i]); cout<<ans<<endl; }
F1题
显然的贪心思路,找到度最多的点选择,之后并查集把其他点取进来
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; int n,m; int in[N]; vector<int> num[N]; queue<int> q; pll ans[N]; int st[N]; int p[N]; int find(int x){ if(x!=p[x]){ p[x]=find(p[x]); } return p[x]; } int main(){ ios::sync_with_stdio(false); cin>>n>>m; int i; for(i=1;i<=n;i++) p[i]=i; for(i=1;i<=m;i++){ int a,b; cin>>a>>b; in[a]++,in[b]++; num[a].push_back(b); num[b].push_back(a); } int mx=0,rt; for(i=1;i<=n;i++){ if(in[i]>mx){ mx=in[i]; rt=i; } } int cnt=0; for(auto x:num[rt]){ p[x]=rt; ans[++cnt]={x,rt}; q.push(x); } while(q.size()){ int t=q.front(); q.pop(); int i; for(auto x:num[t]){ int pa=find(x); int pb=find(t); if(pa!=pb){ p[pa]=pb; ans[++cnt]={x,t}; q.push(x); } } } for(i=1;i<n;i++){ cout<<ans[i].first<<" "<<ans[i].second<<endl; } }
F2题
这题和上一题的思路有些相同,上一题是找最多的点,但是这次我们指定了点数,不难想到,如果先不考虑和1相连的边,那么剩下来的就是一些连通块
而1点需要用D边联通这些连通块,无解情况就是连通块个数大于D,显然无解,还有就是1点的度小于D,那根本连不了D个边,还有一种无解情况是,1无法连通这些连通块
之后构造答案也是如此,先把连通块连好之后,其他用并查集直接维护生成树即可。这题我的代码比较复杂
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; int n,m,d; vector<int> g[N]; vector<int> num[N]; vector<pll> tmp; vector<pll> nxt; int vis[N]; int cnt=0; int flag=0; int p[N]; int id[N]; int st[N]; vector<pll> ans; queue<int> q; void dfs(int u,int fa){ int i; num[cnt].push_back(u); id[u]=cnt; for(i=0;i<(int)g[u].size();i++){ int j=g[u][i]; if(j==fa||vis[j]) continue; vis[j]=1; dfs(j,u); } } int find(int x){ if(x!=p[x]){ p[x]=find(p[x]); } return p[x]; } int main(){ ios::sync_with_stdio(false); cin>>n>>m>>d; int i; for(i=1;i<=n;i++){ p[i]=i; } for(i=1;i<=m;i++){ int a,b; cin>>a>>b; if(a==1||b==1){ tmp.push_back({a,b}); flag++; continue; } g[a].push_back(b); g[b].push_back(a); } for(i=2;i<=n;i++){ if(!vis[i]){ cnt++; vis[i]=1; dfs(i,-1); } } if(cnt>d||flag<d){ cout<<"NO"<<endl; return 0; } for(auto x:tmp){ int a=x.first; int b=x.second; if(a>b) swap(a,b); if(st[id[b]]){ nxt.push_back({a,b}); continue; } d--; st[id[b]]=1; int pa=find(a); int pb=find(b); p[pb]=pa; ans.push_back({a,b}); q.push(b); } for(i=1;i<=cnt;i++){ if(!st[i]){ cout<<"NO"<<endl; return 0; } } for(auto x:nxt){ if(!d) break; int a=x.first; int b=x.second; if(a>b) swap(a,b); int pa=find(a); int pb=find(b); p[pb]=pa; ans.push_back({a,b}); q.push(b); d--; } while(q.size()){ auto t=q.front(); q.pop(); for(auto x:g[t]){ int pa=find(x); int pb=find(t); if(pa!=pb){ ans.push_back({t,x}); p[pa]=pb; q.push(x); } } } cout<<"YES"<<endl; for(auto x:ans){ cout<<x.first<<" "<<x.second<<endl; } }
没有人不辛苦,只有人不喊疼