zoukankan      html  css  js  c++  java
  • CF Gym 100463D Evil (二维前缀和+离散)

    题意:给一些带颜色的点,求一个最小的矩形,恰好包括一半的红色点,且不包括蓝色点。

    题解:暴力,求个二维前缀和,用容斥原理更新一下。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
    ",++cas,area!=INF?area:-1);
        }
        return 0;
    }
  • 相关阅读:
    并发与并行
    OpenCV 图像集合操作
    C++ 输出时间
    绘制模型图
    检测图像文件是否损坏
    QImage,Mat ,QByteArray转换
    图像拼接3
    图像拼接2】
    图像拼接 Stitcher
    《将博客搬至CSDN》
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4665299.html
Copyright © 2011-2022 走看看