看着没人发代码,我扔下我的吧
我的思路大概就是用一个大的矩形把所有的矩形的围住,然后用四条对称轴去切,判断一个点与对称轴对称的点是否也存在,不存在则不能通过这条对称轴切
红色的为对称轴
#include<bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for(int i=(int)(a);i<=(int)(b);i++)
const long long MOD = 1e9 + 7;
const int MAXN = 5e5 + 9;
const int INF = 0x3f3f3f3f;
const double EPS=1e-6;
inline int sgn(double x){
if(x<-EPS)return -1;
return x>EPS;
}
inline int cmp(double x,double y){
return sgn(x-y);
}
long long n,m;
int tot;
struct Point{
double x,y;
void read(){
scanf("%lf%lf",&x,&y);
}
bool operator<(const Point p)const{
if(cmp(x,p.x)==0)return y<p.y;
return x<p.x;
}
bool operator==(const Point p)const{
return cmp(x,p.x)==0&&cmp(y,p.y)==0;
}
Point operator-(const Point p)const{
return (Point){x-p.x,y-p.y};
}
Point operator+(const Point p)const{
return (Point){x+p.x,y+p.y};
}
double len2(){
return x*x+y*y;
}
double operator*(const Point p)const{
return x*p.x+y*p.y;
}
Point operator*(const double d)const{
return (Point){x*d,y*d};
}
Point operator/(const double d)const{
return (Point){x/d,y/d};
}
}p[MAXN];
struct Ans{
double a,b,c;
bool operator<(const Ans s)const{
if(a>s.a)return true;
if(a<s.a)return false;
if(b>s.b)return true;
if(b<s.b)return false;
return c>s.c;
}
}ans[5];
struct Line{
Point s,e;
Point lineProg(Point p){//checked
//`返回点p在直线上的投影`
return s + ( ((e-s)*((e-s)*(p-s)))/((e-s).len2()) );
}
Point symmetryPoint(Point p){
//`返回点p关于直线的对称点`
Point q = lineProg(p);
return (Point){2*q.x-p.x,2*q.y-p.y};
}
};
int now;
bool check(Line line){
rep(i,1,now){//查找所有点的对称点是否在数组里
int l=1,r=now;
bool flag=false;
Point point=line.symmetryPoint(p[i]);
while(l<r-3){//二分查找是否存在
int mid=(l+r)/2;
if(point==p[mid]){
flag=true;
break;
}
if(p[mid]<point)l=mid;
else r=mid;
}
if(flag)continue;
rep(j,l,r){
if(p[j]==point){
flag=true;
break;
}
}
if(!flag)return false;
}
return true;
}
void solve(){
sort(p+1,p+1+4*n);
now=0;
int l=1;
while(l<=4*n){
if(l+1<=4*n){
int r=l+1;
while(r<=4*n&&p[r]==p[l])r++;
if(r==l+1){
p[++now]=p[l];
}
l=r;
}else{
p[++now]=p[l++];
}
}
double mxx=p[1].x,mnx=p[1].x,mxy=p[1].y,mny=p[1].y;
rep(i,1,now){
mxx=max(mxx,p[i].x);
mnx=min(mnx,p[i].x);
mxy=max(mxy,p[i].y);
mny=min(mny,p[i].y);
}
double a,b,c;
int num=0;
Point leftdown={mnx,mny};
Point leftup={mnx,mxy};
Point rightdown={mxx,mny};
Point rightup={mxx,mxy};
a=0,b=2,c=mxy+mny;
Line line;
line={{0,c/2},{1,c/2}};
if(check(line)){
long long cc=c;
if(cc%2==0){
b/=2;c/=2;
}
ans[++num]={a,b,c};
}
a=2,b=0,c=mxx+mnx;
line={{c/2,0},{c/2,1}};
if(check(line)){
long long cc=c;
if(cc%2==0){
a/=2;c/=2;
}
ans[++num]={a,b,c};
}
if(cmp(mxy-mny,mxx-mnx)==0){
a=1,b=-1,c=mnx-mny;
line={leftdown,rightup};
if(check(line)){
ans[++num]={a,b,c};
}
a=1,b=1,c=mnx+mxy;
line={leftup,rightdown};
if(check(line)){
ans[++num]={a,b,c};
}
}
printf("%d\n",num);
sort(ans+1,ans+1+num);
rep(i,1,num){
printf("%.0f %.0f %.0f ",ans[i].a,ans[i].b,ans[i].c);
}
printf("\n");
}
void init(){
scanf("%d",&n);
rep(i,1,n){
p[i*4-3].read();
p[i*4-2].read();
p[i*4-1]=(Point){p[i*4-3].x,p[i*4-2].y};
p[i*4-0]=(Point){p[i*4-2].x,p[i*4-3].y};
}
}
int main() {
int T;
// freopen("data.in","r",stdin);
scanf("%d",&T);
while(T--){
init();
solve();
}
return 0;
}