【题意】
N<=30个点,求两个不touch,不cross的矩形,并求出最大面积和,拼不出两个矩形输出imp.
【解题方法】
暴力对角线两个点,再暴力另外一条对角线两个点,接下来就是对合法性和相交的各种跑判断了,转移这里有一个特别大的坑点,那就是小矩形可能在大矩形里面。。。
【AC 代码】
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=1e5+10,INF=0x3f3f3f3f;
int n;
struct Point{
int x,y;
void read(){
scanf("%d%d",&x,&y);
}
}A[33];
bool vis[205][205];
int l,r,up,down;
void init()
{
memset(vis,false,sizeof(vis));
}
bool online(Point &a,Point &b)
{
return a.x==b.x||a.y==b.y;
}
bool isLegal(Point &a)
{
if(a.x>=l&&a.x<=r&&a.y>=down&&a.y<=up) return 0;
return 1;
}
bool isIn(Point &a){
return (a.x>l&&a.x<r&&a.y>down&&a.y<up);
}
int getArea(Point a,Point b,Point &c,Point &d)
{
if(a.x>b.x) swap(a,b);
c=Point{a.x,b.y};
d=Point{b.x,a.y};
if(vis[c.x][c.y]&&vis[d.x][d.y]) return abs(a.x-b.x)*abs(a.y-b.y);
return -INF;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
if(n==0) break;
init();
for(int i=1; i<=n; i++){
A[i].read();
vis[A[i].x][A[i].y]=true;
}
Point C,D;
int ans=-INF;
//枚举第一条对角线
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(online(A[i],A[j])) continue;
int tmp=getArea(A[i],A[j],C,D);
if(tmp==-INF) continue;
l=min(A[i].x,A[j].x);r=max(A[i].x,A[j].x);
up=max(A[i].y,A[j].y);down=min(A[i].y,A[j].y);
//枚举第二条对角线
for(int k=1; k<=n; k++){
for(int l=1; l<=n; l++){
if(online(A[k],A[l])) continue;
int tmp2=getArea(A[k],A[l],C,D);
if(tmp2==-INF||tmp<tmp2) continue;
if(isIn(A[k])&&isIn(A[l])&&isIn(C)&&isIn(D)){
ans=max(ans,tmp);
}
if(!isLegal(A[k])||!isLegal(A[l])||!isLegal(C)||!isLegal(D)) continue;
ans=max(ans,tmp+tmp2);
}
}
}
}
if(ans==-INF){
puts("imp");
}else{
printf("%d\n",ans);
}
}
}