CF 1455 E. Four Points(模拟加枚举)

链接 https://codeforces.com/problemset/problem/1455/E

You are given four different integer points p1, p2, p3 and p4 on XY grid.

In one step you can choose one of the points pi and move it in one of four directions by one. In other words, if you have chosen point pi=(x,y) you can move it to (x,y+1), (x,y−1), (x+1,y) or (x−1,y).

Your goal to move points in such a way that they will form a square with sides parallel to OX and OY axes (a square with side 0 is allowed).

What is the minimum number of steps you need to make such a square?

Input
The first line contains a single integer t (1≤t≤104) — the number of test cases.

Each test case consists of four lines. Each line contains two integers x and y (0≤x,y≤109) — coordinates of one of the points pi=(x,y).

All points are different in one test case.

Output
For each test case, print the single integer — the minimum number of steps to make a square.

Example
input
3
0 2
4 2
2 0
2 4
1 0
2 0
4 0
6 0
1 6
2 2
2 5
4 1
output
8
7
5
Note
In the first test case, one of the optimal solutions is shown below:
在这里插入图片描述

Each point was moved two times, so the answer 2+2+2+2=8.
In the second test case, one of the optimal solutions is shown below:
在这里插入图片描述

The answer is 3+1+0+3=7.
In the third test case, one of the optimal solutions is shown below:
在这里插入图片描述

The answer is 1+1+2+1=5.

题意
给你四个点,问你最少操作次数,使四个点构成一个正方形。

思路
我们可以通过暴力枚举来做,我们发现我们可以将两个点固定,横坐标或纵坐标的差来确定正方形边长,然后我们求步数,求最小值。
难就难在求步数上,我们将x的1 3固定,y的1 2固定,这样我们每次减去正方形边长后排序,
通过x4 + x3 - x2 - x1 + y4 +y3 - y2 - y1来求步数

代码

#include <bits/stdc++.h>
typedef long long ll;
const ll mod = 9999999967;
using namespace std;
namespace fastIO {
    inline void input(int& res) {
        char c = getchar();res = 0;int f = 1;
        while (!isdigit(c)) { f ^= c == '-'; c = getchar(); }
        while (isdigit(c)) { res = (res << 3) + (res << 1) + (c ^ 48);c = getchar(); }
        res = f ? res : -res;
    }
    inline ll qpow(ll a, ll b) {
        ll ans = 1, base = a;
        while (b) {
            if (b & 1) ans = (ans * base % mod +mod )%mod;
            base = (base * base % mod + mod)%mod;
            b >>= 1;
        }
        return ans;
    }
}
using namespace fastIO;
const int N = 1e6 + 5;

int Case;
struct node{
	ll x;
	ll y;
}zr[5];

int cnt[5];
ll x[5],xx[5],y[5],yy[5];

ll cal(ll d){
	for(int i=1;i<=4;i++){
		xx[i]=x[i],yy[i]=y[i];
	}
	xx[2]-=d,xx[4]-=d,yy[3]-=d,yy[4]-=d;
	sort(xx+1,xx+4+1),sort(yy+1,yy+4+1);
	return xx[4]+xx[3]-xx[2]-xx[1]+yy[4]+yy[3]-yy[2]-yy[1];
}

void solve(){
	for(int i=1;i<=4;i++){
		cnt[i]=i;
		scanf("%lld %lld",&zr[i].x,&zr[i].y);
	}
	ll res = 1e18;
	do{	
		for(int i=1;i<=4;i++){
			x[i]=zr[cnt[i]].x,y[i]=zr[cnt[i]].y;
		}
		res = min(res,cal(x[2]-x[1]));
		res = min(res,cal(x[2]-x[3]));
		res = min(res,cal(x[4]-x[1]));
		res = min(res,cal(x[4]-x[3]));
		res = min(res,cal(y[3]-y[1]));
		res = min(res,cal(y[3]-y[2]));
		res = min(res,cal(y[4]-y[1]));
		res = min(res,cal(y[4]-y[2]));
	}while(next_permutation(cnt+1,cnt+4+1));
	printf("%lld\n",res);
}

int main(){
	Case=1;
	input(Case);
	while(Case--){
		solve();
 	}
	return 0;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值