USACO 5.3 Window Area (矩形切割,上浮法)
2015-03-30 21:03:02
思路:这道题... 不太好用扫描线来做...
我们给每个矩形一个优先级,越上面的优先级越高,由于同时存在添加、删除、置顶、置底多种操作,所以我们可以把优先级的初始值
赋值为一个较大的定值(不妨令为500),这么做的方便之处于,例如:对于第一次置底操作,我们可以让它的优先级=499,小于之前的所有矩形。
接着,对于每一个查看操作,可以采用上浮法,一级一级考虑所有在该矩形上面的矩形(即优先级比它大的),把没有被遮住的部分不断上浮,直到顶上,得到可见的面积。
上浮过程采用DFS递归累加,判断很巧妙,基本可以分成四个部分来算,从别人的博客那里学过来的。
(1)(2)(3)(4)
1 /* 2 ID:naturec1 3 PROG: window 4 LANG: C++ 5 */ 6 #include <cstdio> 7 #include <cstring> 8 #include <cstdlib> 9 #include <cmath> 10 #include <vector> 11 #include <map> 12 #include <set> 13 #include <stack> 14 #include <queue> 15 #include <string> 16 #include <iostream> 17 #include <algorithm> 18 using namespace std; 19 20 #define MEM(a,b) memset(a,b,sizeof(a)) 21 #define REP(i,n) for(int i=0;i<(n);++i) 22 #define FOR(i,a,b) for(int i=(a);i<=(b);++i) 23 #define getmid(l,r) ((l) + ((r) - (l)) / 2) 24 #define MP(a,b) make_pair(a,b) 25 26 typedef long long ll; 27 typedef pair<int,int> pii; 28 const int INF = (1 << 30) - 1; 29 const int MAXN = 10010; 30 31 string str; 32 int pmin,pmax; 33 int tot,id[200]; 34 int pro[MAXN]; 35 36 struct Rec{ 37 int a1,b1,a2,b2; 38 int pro; 39 char id; 40 }R[MAXN]; 41 42 int Dfs(int p,int a1,int b1,int a2,int b2){ 43 if(a1 >= a2 || b1 >= b2) return 0; 44 if(p >= pmax) return (a2 - a1) * (b2 - b1); 45 int res = 0,nxt = pro[p]; 46 if(pro[nxt] == -1) Dfs(p + 1,a1,b1,a2,b2); 47 res += Dfs(p + 1,a1,b1,min(a2,R[nxt].a1),b2); //左半片 48 res += Dfs(p + 1,max(a1,R[nxt].a2),b1,a2,b2); //右半片 49 res += Dfs(p + 1,max(a1,R[nxt].a1),max(b1,R[nxt].b2),min(a2,R[nxt].a2),b2); 50 res += Dfs(p + 1,max(a1,R[nxt].a1),b1,min(a2,R[nxt].a2),min(b2,R[nxt].b1)); 51 return res; 52 } 53 54 int Solve(int cur){ 55 int st = R[cur].pro + 1; 56 return Dfs(st,R[cur].a1,R[cur].b1,R[cur].a2,R[cur].b2); 57 } 58 59 int main(){ 60 freopen("window.in","r",stdin); 61 freopen("window.out","w",stdout); 62 pmin = 499; 63 pmax = 500; 64 while(cin >> str){ 65 int len = str.length(); 66 if(str[0] == 'w'){ 67 R[tot].id = str[2]; //矩形的flag 68 R[tot].pro = pmax++; //矩形的优先级 69 id[(int)str[2]] = tot; // 70 pro[R[tot].pro] = tot; 71 int v[4] = {0},cur = 0; 72 for(int i = 4; i < len - 1; ++i){ 73 if(str[i] == ',') ++cur; 74 else v[cur] = v[cur] * 10 + str[i] - '0'; 75 } 76 R[tot].a1 = min(v[0],v[2]),R[tot].b1 = min(v[1],v[3]); 77 R[tot].a2 = max(v[0],v[2]),R[tot].b2 = max(v[1],v[3]); 78 tot++; 79 } 80 else if(str[0] == 't'){ 81 int cur_id = id[(int)str[2]]; 82 pro[R[cur_id].pro] = -1; 83 R[cur_id].pro = pmax++; 84 pro[R[cur_id].pro] = cur_id; 85 } 86 else if(str[0] == 'b'){ 87 int cur_id = id[(int)str[2]]; 88 pro[R[cur_id].pro] = -1; 89 R[cur_id].pro = pmin--; 90 pro[R[cur_id].pro] = cur_id; 91 } 92 else if(str[0] == 'd'){ 93 int cur_id = id[(int)str[2]]; 94 pro[R[cur_id].pro] = -1; 95 } 96 else{ 97 int cur_id = id[(int)str[2]]; 98 int ans = Solve(cur_id); 99 int total = (R[cur_id].a2 - R[cur_id].a1) * 100 (R[cur_id].b2 - R[cur_id].b1); 101 printf("%.3f\n",(double)ans * 100 / total); 102 } 103 } 104 return 0; 105 }