USACO5.3.2window

USACO5.3.2window

最方便的快捷的方法,当然是离散化。
C++里面有些东西还是不熟啊,比如那个switch
/*
USER: zyn19961
TASK: window
LANG: C++
*/
#include<iostream>
#include<fstream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
//
    using namespace std;
#define MM(a,i) memset(a,i,sizeof(a))
#define FOR(i,l,r) for (int i=(l);i<=(r);i++)
#define PFOR(p,a,next) for(int p=a;p;p=next[p])
//
    typedef long long int64;
    const int INF=~0U>>2;
//
    int maxp=0, minp=0;//maxp最后面的, minp最前面的
    class Window{
        public:
        int x1,y1,x2,y2,pos;
        void init(int a, int b, int c, int d){
            if(a>c)swap(a,c);if(b>d)swap(b,d);
            x1=a,y1=b,x2=c,y2=d,pos=minp--;}
        double area(){return (x2-x1)*(y2-y1);}
        };
    Window  window[256];
    bool map[300][300];
    int hx[50000],hy[50000];
    int fx[1000], fy[1000];
    double query(char ch){
        MM(hx,0),MM(hy,0),MM(fx,0),MM(fy,0);
        int fxn=0,fyn=0;
        //step 1, 找出在ch前面的窗口
        //step 2, 离散化
        FOR(i,0,255)
            if(window[i].pos!=-INF)// && i != ch){
                if(window[i].pos<=window[ch].pos)
                    hx[window[i].x1]=true,hx[window[i].x2]=true,
                    hy[window[i].y1]=true,hy[window[i].y2]=true;
        FOR(i,0,32767){
            if(hx[i])fx[fxn++]=i,hx[i]=fxn-1;//else hx[i]=-1;
            if(hy[i])fy[fyn++]=i,hy[i]=fyn-1;//else hy[i]=-1;
            }
        //step 3, fillflood
        MM(map,false);
        FOR(i,0,255)
            if(window[i].pos!=-INF&&i!=ch){
                if(window[i].pos<window[ch].pos){
                    int bx=hx[window[i].x1],
                        by=hy[window[i].y1];
                    for(int x=bx;fx[x]<window[i].x2; x++)
                        for(int y=by;fy[y]<window[i].y2;y++)
                            map[x][y]=true;
                }
            }
        //step 4, 计算面积百分比
        double area=window[ch].area();
        int bx=hx[window[ch].x1],
            by=hy[window[ch].y1];
        double white=0.0;
        for(int x=bx;fx[x]<window[ch].x2;x++)
            for(int y=by;fy[y]<window[ch].y2;y++){
                if(!map[x][y])
                    white+=(fx[x+1]-fx[x])*(fy[y+1]-fy[y]);
            }
        return white/area;
        }
    int main(){
        freopen("window.in","r",stdin);
        freopen("window.out","w",stdout);
        char op, ch;
        int x1,y1,x2,y2,cnt=0;
        while(scanf("%c",&op) != EOF){
            if (op!='s')
                scanf("(%c,%d,%d,%d,%d)\n",&ch,&x1,&y1,&x2,&y2);
            else
                scanf("(%c)\n",&ch);
            switch(op){
                case 'w': window[ch].init(x1,y1,x2,y2);break;
                case 't': window[ch].pos=minp--; break;
                case 'b': window[ch].pos=maxp++; break;
                case 'd': window[ch].pos=-INF;   break;
                case 's': printf("%.3f\n", query(ch)*100); break;
                default: break;
                }
            }
        return 0;
        }

你可能感兴趣的:(USACO5.3.2window)