USACO 5.3 Window Area

第一次做矩形切割的题目,所谓的矩形切割。。其实就是,矩形a与矩形b重叠,其中a在下面,b在上面,我们要知道a有多少面积可以被看见。在多个矩形重叠的情况下,一般先按重叠次序排一下序,然后从要询问的那个开始一次与他上面相邻的矩形比较,每次把不重叠的左边、右边、上边、下边一部分分别割成4个小矩形,然后每个小矩形递归的向上计算(也可以使用队列迭代),然后最终的总和就是结果。这就是所谓的矩形切割。。
此题的数据量很小,矩形的数目非常有限,所以基本上不用考虑时间问题,算法想出来后,注意一下细节的实现,基本上就过了。。
这题把update和tot的更新放反了。。。结果在最后一组test上面WA了半小时。。。

/*
ID: zlqest11
LANG: C++
TASK: window
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

struct node{
char lab;
int x1, y1, x2, y2, h;
void init(char ch, int a, int b, int c, int d, int e){
lab = ch;
x1 = min(a,c), y1 = min(b,d), x2 = max(a,c), y2 = max(b,d), h = e;
}
}win[65];
int tot, minh, maxh;

typedef long long llg;

void update(){
for(int i = 0; i < tot; i++){
minh = min(minh, win[i].h);
maxh = max(maxh, win[i].h);
}
}

bool cmp(const node &a, const node &b){
return a.h < b.h;
}

llg rec(int x1, int y1, int x2, int y2, int pos){
if(pos == tot) return (llg)(x2-x1)*(y2-y1);
llg ans = 0;
if(x1 < win[pos].x1) ans += rec(x1,y1,min(x2,win[pos].x1),y2,pos+1);
if(x2 > win[pos].x2) ans += rec(max(win[pos].x2,x1),y1,x2,y2,pos+1);
if(x2>win[pos].x1 && x1<win[pos].x2 && y2>win[pos].y2)
ans += rec(max(x1, win[pos].x1), max(y1, win[pos].y2), min(x2, win[pos].x2), y2, pos+1);
if(x2>win[pos].x1 && x1<win[pos].x2 && y1<win[pos].y1)
ans += rec(max(x1, win[pos].x1), y1, min(x2, win[pos].x2), min(y2, win[pos].y1), pos+1);
return ans;
}

int main()
{
char str[50];
char lab;
int x1, y1, x2, y2;
int Case = 0;
freopen("window.in", "r", stdin);
freopen("window.out", "w", stdout);
minh = maxh = tot = 0;
while(scanf("%s", str) != EOF){
if(str[0] == 'w'){
sscanf(str, "w(%c,%d,%d,%d,%d)", &lab, &x1, &y1, &x2, &y2);
win[tot].init(lab, x1, y1, x2, y2, maxh+1);
tot++;
update();
}
if(str[0] == 't'){
sscanf(str, "t(%c)", &lab);
for(int i = 0; i < tot; i++){
if(win[i].lab == lab){
win[i].h = maxh+1;
update();
break;
}
}
}
if(str[0] == 'b'){
sscanf(str, "b(%c)", &lab);
for(int i = 0; i < tot; i++){
if(win[i].lab == lab){
win[i].h = minh-1;
update();
break;
}
}
}
if(str[0] == 'd'){
sscanf(str, "d(%c)", &lab);
for(int i = 0; i < tot; i++){
if(win[i].lab == lab){
for(int j = i; j < tot; j++) win[j] = win[j+1];
tot--;
update();
break;
}
}
}
if(str[0] == 's'){
++Case;
sscanf(str, "s(%c)", &lab);
sort(win, win+tot, cmp);
for(int i = 0; i < tot; i++){
if(win[i].lab == lab){
llg area = rec(win[i].x1, win[i].y1, win[i].x2, win[i].y2, i+1);
printf("%.3f\n", (double)area*100.0/(win[i].x2-win[i].x1)/(win[i].y2-win[i].y1));
break;
}
}
}
}
return 0;
}



posted on 2012-02-14 11:08  Moon_1st  阅读(264)  评论(0编辑  收藏  举报

导航