标签:
题意:给一些带颜色的点,求一个最小的矩形,恰好包括一半的红色点,且不包括蓝色点。
题解:暴力,求个二维前缀和,用容斥原理更新一下。N很小所以我采用了离散优化,跑了个0ms。
之前没写过二维前缀和,加上离散写得也不是很熟练,所以搞了2个小时,好在是一发就过了。貌似有个坑,线不要特判,不然wa。
#include<cstdio> #include<cmath> #include<vector> #include<map> #include<set> #include<algorithm> #include<cstring> using namespace std; //#define local const int maxn = 25; int Red; int X[maxn],szx; int Y[maxn],szy; int G[maxn][maxn]; int sumb[maxn][maxn]; int suma[maxn][maxn]; struct Poi { int x,y; int tp; int sx,sy; bool operator < (const Poi & rhs) const { return x < rhs.x || (x == rhs.x && y < rhs.y); } void input(){ scanf("%d%d%d",&x,&y,&tp); if(!tp)Red++; } void GetDis(){ sx = lower_bound(X,X+szx,x)-X; sy = lower_bound(Y,Y+szy,y)-Y; G[sx][sy] = tp; } }P[maxn]; const int INF = 0x7fffffff; int main() { #ifdef local freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif // local int N; int cas = 0; while(~scanf("%d",&N)&&N){ Red = 0; memset(G,-1,sizeof(G)); int minx = INF, miny = INF; for(int i = 0 ; i < N; i++){ P[i].input(); minx = min(minx,P[i].x); miny = min(miny,P[i].y); //Y[i] = P[i].y; } X[0] = minx-1; Y[0] = miny-1 ; for(int i = 1; i <= N; i++) { X[i] = P[i-1].x; Y[i] = P[i-1].y; } sort(X,X+N+1); sort(Y,Y+N+1); szy = unique(Y,Y+N+1) - Y; szx = unique(X,X+N+1) - X; memset(suma,0,sizeof(suma)); memset(sumb,0,sizeof(sumb)); for(int i = 0; i < N; i++) P[i].GetDis(); for(int i = 1; i < szx; i++) for(int j = 1; j < szy; j++){ suma[i][j] = suma[i-1][j]+suma[i][j-1]-suma[i-1][j-1]+(G[i][j]==1); sumb[i][j] = sumb[i-1][j]+sumb[i][j-1]-sumb[i-1][j-1]+(G[i][j]==0); } Red >>= 1; int area = INF; for(int lx = 0; lx < szx; lx++){ for(int rx = lx+1; rx < szx; rx++){ for(int ly = 0; ly <szy; ly++){ for(int ry = ly+1; ry < szy; ry++){ if(suma[rx][ry]-suma[rx][ly]-suma[lx][ry]+suma[lx][ly]) continue; if(Red == sumb[rx][ry]-sumb[rx][ly]-sumb[lx][ry]+sumb[lx][ly]){ area = min(area,(X[rx]-X[lx+1])*(Y[ry]-Y[ly+1])); } } } } } printf("Case %d: %d\n",++cas,area!=INF?area:-1); } return 0; }
标签:
原文地址:http://www.cnblogs.com/jerryRey/p/4665299.html