P12816 [NERC 2021] Connect the Points
题目描述
给定平面上的三个点。你需要选择若干条与坐标轴平行的线段,使得这三个点相互连通。所选线段的总长度应尽可能短。
当两个点 aaa 和 bbb 之间存在一系列点 p0=a,p1,…,pk=bp_0 = a, p_1, \ldots, p_k = bp0=a,p1,…,pk=b,且每对相邻点 pip_ipi 和 pi+1p_{i+1}pi+1 位于同一条线段上时,我们认为这两个点是连通的。
输入格式
输入包含三行,每行描述一个点。每行包含两个用空格分隔的整数 xxx 和 yyy —— 点的坐标(−109≤x,y≤109-10^9 \le x, y \le 10^9−109≤x,y≤109)。这些点两两不同。
输出格式
第一行输出 nnn —— 线段的数量,最多为 100。
接下来的 nnn 行应描述每条线段。每行输出四个整数 x1x_1x1, y1y_1y1, x2x_2x2, y2y_2y2 —— 对应线段端点的坐标(−109≤x1,y1,x2,y2≤109-10^9 \le x_1, y_1, x_2, y_2 \le 10^9−109≤x1,y1,x2,y2≤109)。每条线段必须水平或垂直。
题目保证在给定约束条件下存在解。
输入输出样例 #1
输入 #1
1 1
3 5
8 6
输出 #1
3
1 1 1 5
1 5 8 5
8 5 8 6
说明/提示
样例中的点和线段如下图所示。

翻译由 DeepSeek V3 完成
C++实现
#include<bits/stdc++.h>
using namespace std;
struct cat{
int a,b,c,d;
}ans[15];
int siz;
struct fish{
int x,y;
}a[3];
bool cmp(fish x,fish y){
if(x.x==y.x)return x.y<y.y;
return x.x<y.x;
}
int main(){
cin>>a[0].x>>a[0].y;
cin>>a[1].x>>a[1].y;
cin>>a[2].x>>a[2].y;
sort(a,a+3,cmp);
if(a[0].x!=a[1].x)
ans[++siz]={a[0].x,a[0].y,a[1].x,a[0].y};
if(a[0].y!=a[1].y)
ans[++siz]={a[1].x,a[0].y,a[1].x,a[1].y};
if(a[0].y>=a[2].y&&a[1].y<=a[2].y||a[0].y<=a[2].y&&a[1].y>=a[2].y){
ans[++siz]={a[1].x,a[2].y,a[2].x,a[2].y};
}else{
int xx=siz;
if(abs(ans[xx].a-a[2].x)+abs(ans[xx].b-a[2].y)>=
abs(a[1].x-a[2].x)+abs(a[1].y-a[2].y)){
if(a[1].x!=a[2].x)
ans[++siz]={a[1].x,a[1].y,a[2].x,a[1].y};
if(a[1].y!=a[2].y)
ans[++siz]={a[2].x,a[1].y,a[2].x,a[2].y};
}else{
if(ans[xx].a!=a[2].x)
ans[++siz]={ans[xx].a,ans[xx].b,a[2].x,ans[xx].b};
if(ans[xx].b!=a[2].y)
ans[++siz]={a[2].x,ans[xx].b,a[2].x,a[2].y};
}
}
cout<<siz<<'\n';
for(int i=1;i<=siz;i++)
cout<<ans[i].a<<' '<<ans[i].b<<' '<<ans[i].c<<' '<<ans[i].d<<'\n';
return 0;
}

后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容
用C++实现信奥 P12816 NERC 2021 Connect the Points&spm=1001.2101.3001.5002&articleId=153107109&d=1&t=3&u=d6b05598419d45eca2db16a7fe8b90d0)
195

被折叠的 条评论
为什么被折叠?



