E. Four Points
题意:
给你四个点。
现在提供操作,可以移动一个点。
要求你进行最小的操作,来构造一个正方形,使得所有的点都平行于x轴和y轴。
思路(主要是对jangly代码的解读,jangly,tql)
- 确定正方形为。
1 3
0 2
- 之后枚举每一条边
std::vector<int> cand{0};
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
cand.push_back(p[2 + j].first - p[i].first);
cand.push_back(p[2 * j + 1].second - p[2 * i].second);
}
}
- 枚举计算时。
res += abs(x[i]-x[1]);
//ans = min(ans, -v[0]-v[1]+v[2]+v[3]-w[0]-w[1]+w[2]+w[3]);
res += abs(y[i]-y[1]);
- 要枚举作为起点的角落(通过排列,来确定四个点的位置)
do{
....
.....
}while(next_permutation(p, p+4));//枚举作为起点的角落。
AC
#include <bits/stdc++.h>
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int t;
std::cin >> t;
while (t--) {
int64_t ans = 1e18;
std::pair<int, int> p[4];
for (int i = 0; i < 4; ++i) std::cin >> p[i].first >> p[i].second;
std::sort(p, p + 4);
do {
std::vector<int> cand{0};
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 2; ++j) {
cand.push_back(p[2 + j].first - p[i].first);
cand.push_back(p[2 * j + 1].second - p[2 * i].second);
}
}
for (auto d : cand) {
if (d < 0) continue;
int64_t res = 0;
int x[4], y[4];
for (int i = 0; i < 4; ++i) std::tie(x[i], y[i]) = p[i];
x[2] -= d, x[3] -= d;
y[1] -= d, y[3] -= d;
std::sort(x, x + 4);
std::sort(y, y + 4);
for (int i = 0; i < 4; ++i) {
res += std::abs(x[i] - x[1]);
res += std::abs(y[i] - y[1]);
}
if (res < ans) ans = res;
}
} while (std::next_permutation(p, p + 4));
std::cout << ans << "\n";
}
return 0;
}
AC
#include <iostream>
#include <bits/stdc++.h>
#define For(i,x,y) for(int i=(x); i<=(y); i++)
#define fori(i,x,y) for(int i=(x); i<(y); i++)
#define rep(i,y,x) for(int i=(y); i>=(x); i--)
#define mst(x,a) memset(x,a,sizeof(x))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<int,int>pa;
typedef pair<ll,ll>pai;
int main()
{
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
int tt; cin>>tt;
while(tt--){
ll ans = 1e18;
pa p[4];
fori(i,0,4)cin>>p[i].fi>>p[i].se;
sort(p, p+4);
do{
vector<int>cand;
fori(i,0,2)fori(j,0,2){
cand.pb(p[i+2].fi - p[j].fi);
cand.pb(p[j*2+1].se - p[i*2].se);
}
for(auto d: cand){
if(d<=0)continue;
int x[4], y[4];
fori(i,0,4)tie(x[i],y[i]) = p[i];
x[2] -= d; x[3] -= d;
y[1] -= d; y[3] -= d;
sort(x, x+4);
sort(y, y+4);
ll res = 0;
fori(i,0,4){
res += abs(x[i]-x[1]);
//ans = min(ans, -v[0]-v[1]+v[2]+v[3]-w[0]-w[1]+w[2]+w[3]);
res += abs(y[i]-y[1]);
}
if(ans>res) ans = res;
}
}while(next_permutation(p, p+4));//枚举作为起点的角落。
cout<<ans<<endl;
}
return 0;
}