打卡信奥刷题(2210)用C++实现信奥 P12816 [NERC 2021] Connect the Points

P12816 [NERC 2021] Connect the Points

题目描述

给定平面上的三个点。你需要选择若干条与坐标轴平行的线段,使得这三个点相互连通。所选线段的总长度应尽可能短。

当两个点 aaabbb 之间存在一系列点 p0=a,p1,…,pk=bp_0 = a, p_1, \ldots, p_k = bp0=a,p1,,pk=b,且每对相邻点 pip_ipipi+1p_{i+1}pi+1 位于同一条线段上时,我们认为这两个点是连通的

输入格式

输入包含三行,每行描述一个点。每行包含两个用空格分隔的整数 xxxyyy —— 点的坐标(−109≤x,y≤109-10^9 \le x, y \le 10^9109x,y109)。这些点两两不同。

输出格式

第一行输出 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^9109x1,y1,x2,y2109)。每条线段必须水平或垂直。

题目保证在给定约束条件下存在解。

输入输出样例 #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考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值