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;
}