3 / 10 3/10 3/10 想到 d f s dfs dfs 就差不多有解题思路了
在二维平面上,有 N N N 个不同的点。给出每个点的坐标。 你希望丢掉三个点,然后用一个矩形把所有的点全部框起来。 求出那个矩形的最小面积。
5 ≤ N ≤ 50000 5\le N\le 50000 5≤N≤50000 1 ≤ X i , Y i ≤ 40000 1\le X_i,Y_i\le 40000 1≤Xi,Yi≤40000
时间复杂度 O ( 64 × N ) O(64\times N) O(64×N) Times:156(MS)
/* _ __ __ _ _ | | \ \ / / | | (_) | |__ _ _ \ V /__ _ _ __ | | ___ _ | '_ \| | | | \ // _` | '_ \| | / _ \ | | |_) | |_| | | | (_| | | | | |___| __/ | |_.__/ \__, | \_/\__,_|_| |_\_____/\___|_| __/ | |___/ */ int n; struct pt{ int x; int y; }aa[50050]; vector<int>PX[40050]; /// PX[T] 表示储存横坐标为 T 的所有点的编号 vector<int>PY[40050]; /// PY[T] 表示储存纵坐标为 T 的所有点的编号 bool vis[50050]; /// vis[T] 表示已经删掉了点 T int cal(){ /// 计算最小围住的矩形面积 int Max = 0,May = 0; int Mix = INF,Miy = INF; for(int i = 1;i <= n;i ++){ if(vis[i])continue; Max = max(Max,aa[i].x); May = max(May,aa[i].y); Mix = min(Mix,aa[i].x); Miy = min(Miy,aa[i].y); } return (Max - Mix) * (May - Miy); } int dfs(int c,int shu){ /// c表示第几次删除层数(貌似不必要的),shu表示还能删几个点 if(c == 4)return cal(); if(shu == 0)return cal(); int tmp = 0; int MaX = 0; int MaY = 0; int MiX = INF; int MiY = INF; for(int i = 1;i<=n;++i){ /// 算出了最小围住矩形的面积 if(vis[i])continue; /// 也算出了矩形的边界的横纵坐标 MaX = max(MaX,aa[i].x); MaY = max(MaY,aa[i].y); MiX = min(MiX,aa[i].x); MiY = min(MiY,aa[i].y); } tmp = (MaX - MiX) * (MaY - MiY); /// 删掉哪条边?四种情况都一一枚举 /// right if(PX[MaX].size() <= shu){ for(int i = 0;i<PX[MaX].size();++i) vis[PX[MaX][i]] = 1; tmp = min(tmp,dfs(c+1,shu - PX[MaX].size())); for(int i = 0;i<PX[MaX].size();++i) vis[PX[MaX][i]] = 0; } /// left if(PX[MiX].size() <= shu){ for(int i = 0;i<PX[MiX].size();++i) vis[PX[MiX][i]] = 1; tmp = min(tmp,dfs(c+1,shu - PX[MiX].size())); for(int i = 0;i<PX[MiX].size();++i) vis[PX[MiX][i]] = 0; } /// up if(PY[MaY].size() <= shu){ for(int i = 0;i<PY[MaY].size();++i) vis[PY[MaY][i]] = 1; tmp = min(tmp,dfs(c+1,shu - PY[MaY].size())); for(int i = 0;i<PY[MaY].size();++i) vis[PY[MaY][i]] = 0; } /// down if(PY[MiY].size() <= shu){ for(int i = 0;i<PY[MiY].size();++i) vis[PY[MiY][i]] = 1; tmp = min(tmp,dfs(c+1,shu - PY[MiY].size())); for(int i = 0;i<PY[MiY].size();++i) vis[PY[MiY][i]] = 0; } return tmp; } int main() { scanf("%d",&n); for(int i = 1;i <= n;i ++){ scanf("%d%d",&aa[i].x,&aa[i].y); PX[aa[i].x].push_back(i); PY[aa[i].y].push_back(i); } printf("%d",dfs(1,3)); return 0; }