Codeforces Round #541題解
阿新 • • 發佈:2020-12-22
A題
通過平移線段可以發現其實就是缺少的那一塊的大小
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; int main(){ ios::sync_with_stdio(false); ll a,b,c,d; cin>>a>>b>>c>>d; cout<<(a+2)*(b+d+2)-d*(a-c)-a*b-c*d<<endl;View Codereturn 0; }
B題
思維題,因為我們肯定是最優策略,因此當前兩個點的最小值和前面的兩個最大值的差值相減,但是要和0取max
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; int a[N],b[N]; int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i;View Codefor(i=2;i<=n+1;i++) cin>>a[i]>>b[i]; ll ans=1; a[1]=b[1]=0; n++; for(i=1;i<=n;i++){ ans+=max(0,min(a[i],b[i])-max(a[i-1],b[i-1])+1); if(a[i-1]==b[i-1]) ans--; } cout<<ans<<endl; return 0; }
C題
肯定是先遞增後遞減最好,因為不是這樣,最大值無論移到哪裡都會變劣
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=5e5+10; int a[N],b[N]; queue<int> q1; stack<int> q2; int main(){ ios::sync_with_stdio(false); int n; cin>>n; int i,j,k; for(i=1;i<=n;i++){ cin>>a[i]; } sort(a+1,a+1+n); for(i=1;i<=n;i++){ if(i&1) q1.push(a[i]); else q2.push(a[i]); } while(q1.size()){ cout<<q1.front()<<" "; q1.pop(); } while(q2.size()){ cout<<q2.top()<<" "; q2.pop(); } return 0; }View Code
D題
E題
F題
能看的出是並查集的思路,有兩種做法,一種是啟發式合併,一種是維護頭結點之後跑dfs
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<int,int> pll; const int N=2e5+10; int p[N]; int n; vector<int> num[N]; int find(int x){ if(x!=p[x]){ p[x]=find(p[x]); } return p[x]; } void dfs(int u){ int i; cout<<u<<" "; for(i=0;i<num[u].size();i++){ int j=num[u][i]; dfs(j); } } int main(){ ios::sync_with_stdio(false); cin>>n; int i; for(i=1;i<=n;i++){ p[i]=i; } for(i=1;i<n;i++){ int a,b; cin>>a>>b; int pa=find(a); int pb=find(b); p[pa]=pb; num[pb].push_back(pa); } for(i=1;i<=n;i++){ if(p[i]==i){ dfs(i); break; } } return 0; }View Code
G題