测试数据随机,给2n个点,求所有偏移量,使得每两个点成为一个匹配
题目
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxn = 2e5 + 5;
int n;
struct Poi{
int x, y;
// Poi() = default;
// Poi(int x, int y): x(x), y(y) {}
Poi operator-(Poi u){
// Poi res = {abs(x - u.x), abs(y - u.y)};不能直接都取绝对值
// return res;
return Poi{(x - u.x), (y - u.y)};
}
Poi operator+(Poi u){
return Poi{x + u.x, y + u.y};
}
bool operator<(const Poi &u)const{//整段不能去掉,不然报错
if(x != u.x) return x < u.x;
return y < u.y;
}
}point[maxn];
bool mp[maxn];
map<Poi, int> cnt;
bool check(Poi d){
// for(int i = 1; i <= 2 * n; i++){
// mp[i] = 0;
// }
int match = 0;
int dx = d.x, dy = d.y;
// for(int i = 1; i <= 2 * n; i++){
// if(mp[i]) continue;
// for(int j = i + 1; j <= 2 * n; j++){
// Poi dd = point[i] - point[j];
// if((dd.x == d.x && dd.y == dd.y)){
// mp[i] = 1;
// mp[j] = 1;
// break;
// }
// }
// if(!mp[i]) return 0;
// }
// return 1;
map<Poi, int> tmp = cnt;
for(int i = 1; i <= 2 * n; i++){
int x = point[i].x, y = point[i].y;
Poi u = {x + dx, y + dy};
if(tmp[u] && tmp[point[i]]){
tmp[u]--;
tmp[point[i]]--;
match++;
}
}
return match == n;
}
void solve(){
map<Poi, bool> vis;
cnt.clear();
int i, j;
cin >> n;
for(i = 1; i <= 2 * n; i++){
cin >> point[i].x >> point[i].y;
cnt[point[i]]++;
}
Poi d;
vector<Poi> ans;
for(i = 2; i <= 2 * n; i++){
d = point[1] - point[i];
if(d.x < 0) d.x = -d.x, d.y = -d.y;
if(vis[d]) continue;
vis[d] = 1;
bool flag = 1;
for(int j = 2; j <= 2 * n; j++){
Poi u = point[j] + d;
Poi v = point[j] - d;
if(!cnt[u] && !cnt[v]){
flag = 0;
break;
}
}
if(!flag) continue;
if(check(d)){
ans.push_back(d);
if(!(d.x == 0 && d.y == 0)) ans.push_back({-d.x, -d.y});
}
}
cout << ans.size() << '\n';
sort(ans.begin(), ans.end());
for(auto p : ans){
cout << p.x << ' ' << p.y << '\n';
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
return 0;
}