Codeforces Round #528 (Div. 2, based on Technocup 2019 Elimination Round 4)題解
阿新 • • 發佈:2018-12-24
2018-12-24晚小上一波分,這套比賽差點翻車,還好最後15分鐘弄出了C,交C的
時候心裡一點底都沒有,因為C的情況可能超過我的想象,現在看來我的擔心是不
必要的。。。然後倒數20多秒絕殺了D題。。這道題很有自信樣例都沒測直接交果
然也過了,後面的題目都沒時間來得及看。。。賽後補好了。
A題和B題太水了不寫題解。。
C. Connect Three
題意:
平面上有A,B,C三個點,用最短的路徑連線它們,輸出最短路徑長度、最短路徑(任意順序輸出均可)。
思路:
容易發現最短路徑長度是最高點-最低點+最右點-最左點+1,麻煩在於怎麼輸出路徑。
這道題情況很多,直接模擬每種情況可以寫但是比較麻煩,這裡介紹一下我的方法。如下圖所示,
我們可以按照x從小到大排下序,然後確定一下他們的匯合點,這個匯合點D的座標Dx=Bx,Dy=Cy;
然後我們可以分別從A,B,C出發連到D去,連的時候記得對走過的路徑打上標記就ojbk了。
程式碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 struct node{ 5 int x,y; 6 }a[10]; 7 bool cmp(node a,node b){8 return a.x<b.x; 9 } 10 bool cmp1(node a,node b){ 11 return a.y<b.y; 12 } 13 int vis[1005][1005]; 14 int main(){ 15 cin>>a[1].x>>a[1].y>>a[2].x>>a[2].y>>a[3].x>>a[3].y; 16 sort(a+1,a+4,cmp); 17 int l=9999,r=0,u=0,d=9999; 18 for(int i=1;i<=3;i++){ 19 l=min(l,a[i].y); 20 r=max(r,a[i].y); 21 u=max(u,a[i].x); 22 d=min(d,a[i].x); 23 } 24 //printf("%d %d %d %d\n",l,r,d,u); 25 int ans=r-l+u-d+1; 26 printf("%d\n",ans); 27 int x=a[2].x; 28 sort(a+1,a+4,cmp1); 29 int y=a[2].y; 30 for(int i=1;i<=3;i++){ 31 if(x==a[i].x){ //輸出B到D的路徑 32 int s=a[i].y; 33 int e=y; 34 if(s>e)swap(s,e); 35 for(int j=s;j<=e;j++){ 36 if(!vis[x][j]){ 37 vis[x][j]=1; 38 printf("%d %d\n",x,j); 39 } 40 } 41 } 42 else if(y==a[i].y){ //輸出C到D的路徑 43 int s=a[i].x; 44 int e=x; 45 if(s>e)swap(s,e); 46 for(int j=s;j<=e;j++){ 47 if(!vis[j][y]){ 48 vis[j][y]=1; 49 printf("%d %d\n",j,y); 50 } 51 } 52 } 53 else{ //輸出A到D的路徑 54 int s=a[i].x; 55 int e=x; 56 if(s>e)swap(s,e); 57 for(int j=s;j<=e;j++){ 58 if(!vis[j][y]){ 59 vis[j][y]=1; 60 printf("%d %d\n",j,y); 61 } 62 } 63 s=a[i].y; 64 e=y; 65 if(s>e)swap(s,e); 66 for(int j=s;j<=e;j++){ 67 if(!vis[a[i].x][j]){ 68 vis[a[i].x][j]=1; 69 printf("%d %d\n",a[i].x,j); 70 } 71 } 72 } 73 } 74 }
D. Minimum Diameter Tree
題意:
給你一棵有n個節點的樹,再給你一個s,構造這棵數的邊權讓他們的和加起來等於s,
求這棵樹的最短直徑,最短直徑定義為樹上任意兩個節點的距離的最大值。
思路:
看樣例容易看出答案跟葉子節點的個數有關,ans=s*2/葉子節點個數。
為什麼呢?我們按照貪心來想,當把s全給平均分配給葉子節點的時候肯定是最優的,證畢。
程式碼:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 vector<int>g[100005]; 5 int ans=0; 6 void dfs(int u,int fa){ 7 if(g[u].size()==1){ 8 ans++; 9 if(u!=1)return; 10 } 11 for(int i=0;i<g[u].size();i++){ 12 int v=g[u][i]; 13 if(v==fa)continue; 14 dfs(v,u); 15 } 16 } 17 int main(){ 18 int n; 19 double s; 20 scanf("%d%lf",&n,&s); 21 for(int i=1;i<n;i++){ 22 int x,y; 23 scanf("%d%d",&x,&y); 24 g[x].push_back(y); 25 g[y].push_back(x); 26 } 27 dfs(1,1); 28 double res=s/ans*2; 29 printf("%.18lf\n",res); 30 }
E、F題太難補不動。溜了溜了