Codeforces 1455E. Four Points(枚举/贪心/几何)

58 篇文章 0 订阅
35 篇文章 1 订阅

Educational Codeforces Round 99 (Rated for Div. 2) 全文见:https://blog.csdn.net/qq_43461168/article/details/113105113

E. Four Points

题意:给四个点。移动他们,使得形成一个正方形。 求最小移动步数。

思路参考:https://www.cnblogs.com/qieqiemin/p/14069636.html

思路: x和y可以分开考虑。 首先枚举每个点作为四个点的任意一个点。也就是枚举所有排列。然后再进行计算。单独考虑x。设左下,右下,左上,右上,分别为 p0,p1,p2,p3。然后对于 p0-p2,可以求出一个x的范围 x1-x2。就是min(p0.x,p2.x) - max(p0.x,p2.x) 。同理对于 p1-p3 一样求。然后就会得出两个区间。 如果左边小于右边。那就让他们移动到各自的中点去就行了。这样移动距离是最小的。如果右边 小于左边。那就全部移动到min(p0.x,p2.x)就好了。边长为0也是合法的。对于y轴。是一样考虑的。这时候。得到了一个 水平的边长范围。和一个竖直的边长范围。如果 横着和竖着有交集。那就直接是 costx+costy。就是总的cost。如果没有交集。那必然需要两个点做出让步。移动到边长相等的地方去。这就加上额外的cost就行了。

AC代码:

#include <bits/stdc++.h>
#define int long long
#define mk make_pair
using namespace std;
const int N = 1e6+7;
const int mod = 1e9+7;
int t = 1,n,m,k;
struct node{
    int x,y;
}p[N];
int sum[N];

set<pair<int,int> > st;

signed main(){
    cin>>t;
    while(t-- ){
        int b[] = {0,1,2,3};
        for(int i = 0 ; i < 4 ; i ++){
            cin>>p[i].x>>p[i].y;
        }
        int res = 1e18;
        do{
            int x1 = min(p[b[0]].x,p[b[2]].x);
            int x2 = max(p[b[0]].x,p[b[2]].x);
            int x3 = min(p[b[1]].x,p[b[3]].x);
            int x4 = max(p[b[1]].x,p[b[3]].x);

            int y1 = min(p[b[0]].y,p[b[1]].y);
            int y2 = max(p[b[0]].y,p[b[1]].y);
            int y3 = min(p[b[2]].y,p[b[3]].y);
            int y4 = max(p[b[2]].y,p[b[3]].y);

            int costx,costy;
            int x_l,x_r,y_l,y_r;

            if (x4 < x1) {
                x_l = x_r = 0;
                costx = x2 - x3 + x1 - x4;
            } else {
                x_l = max(x3 - x2, 0ll);
                x_r = x4 - x1;
                costx = x2 - x1 + x4 - x3;
            }

            if (y4 < y1) {
                y_l = y_r = 0;
                costy = y2 - y3 + y1 - y4;
            } else {
                y_l = max(y3 - y2, 0ll);
                y_r = y4 - y1;
                costy = y2 - y1 + y4 - y3;
            }

            int cost = costx + costy;
            if (y_l > x_r) {
                cost += (y_l - x_r) << 1;
            } else if (x_l > y_r) {
                cost += (x_l - y_r) << 1;
            }
            res = min(res, cost);
        }while(next_permutation(b,b+4));
        cout<<res<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值