USACO 5.3 Window Area
IV Balkan Olympiad
You've just be assigned the project of implemented a windowing interface. This windowing interface is fairly simple, and fortunately, you don't have to display the actual windows. There are 5 basic operations:
- Create a window
- Bring a window to the top
- Put a window to the bottom
- Destroy a window
- Output what percentage of a window is visible (i.e., isn't covered by windows above it).
In the input, the operations appear in the following format:
- Create window: w(I,x,y,X,Y)
- Bring window to top: t(I)
- Put window on bottom: b(I)
- Destroy window: d(I)
- Output percentage visible: s(I)
The I is a unique identifier for each window, which is one character. The character can be any of 'a'..'z', 'A'..'Z', and '0'..'9'. No extra spaces will appear in the input.
(x,y) and (X,Y) are opposite corners of the window. When a window is created, it is put `on top'. You can't create a window with an identifier that is already in use, but you can destroy a window and then create a new one with the identifier of the destroyed window. Coordinates will be positive integers, and all windows will be of non-zero area (x != X and y != Y). The x and y coordinates are between 1 and 32767 inclusive.
PROGRAM NAME: window
INPUT FORMAT
The input file consists of a sequence of commands to your interpreter. They will be listed one per line. Terminate the program when no more input is available
SAMPLE INPUT (file window.in)
w(a,10,132,20,12) w(b,8,76,124,15) s(a)
OUTPUT FORMAT
Output lines only for the s() commands. Of course, there might be several s() commands (but no more than 500) so the output should be a sequence of percentages, one per line, stating the percentage of the windows that are visible. The percentages should be rounded to 3 decimal places.
SAMPLE OUTPUT (file window.out)
49.167
——————————————————————————————题解
借用USACO的字符画一下
*----------------* | | | | | | | *----* | | | | | | | | | | | | | | *----* | | | | | *----------------* || \/ *-----*----*-----* | | | | | | 2 | | | | | | | *----* | | | | | | 1 | | 3 | | | | | | *----* | | | 4 | | | | | | *-----*----*-----* *-----* | 2 | | | *------------------* | | | | *------------------* | 4 | | | *-----* *------------* | | *-------| | | | | | | | | 1 *------------* | | 4 | *-------*---*
这样上下左右的切割,递归处理
前四个操作只要记录一下高度值,修改高度就可以了
1 /* 2 ID: ivorysi 3 LANG: C++ 4 PROG: window 5 */ 6 #include <iostream> 7 #include <cstdio> 8 #include <cstring> 9 #include <algorithm> 10 #include <queue> 11 #include <set> 12 #include <vector> 13 #include <string.h> 14 #include <cmath> 15 #define siji(i,x,y) for(int i=(x);i<=(y);++i) 16 #define gongzi(j,x,y) for(int j=(x);j>=(y);--j) 17 #define xiaosiji(i,x,y) for(int i=(x);i<(y);++i) 18 #define sigongzi(j,x,y) for(int j=(x);j>(y);--j) 19 #define inf 0x3f3f3f3f 20 #define ivorysi 21 #define mo 97797977 22 #define hash 974711 23 #define base 47 24 #define pss pair<string,string> 25 #define MAXN 5000 26 #define fi first 27 #define se second 28 #define pii pair<int,int> 29 #define esp 1e-8 30 typedef long long ll; 31 using namespace std; 32 char a[50]; 33 int f,cut[205]; 34 int cnt; 35 struct data{ 36 int lx,ly,rx,ry; 37 int h; 38 }window[205]; 39 int calc(char c) { 40 if(c>='a' && c<='z') return c-'a'+1; 41 else if (c>='A' && c<='Z') return c-'A'+27; 42 else if(c>='0' && c<='9') return c-'0'+53; 43 } 44 void ins(int x,int y,int X,int Y,char c) { 45 int t=calc(c); 46 ++cnt; 47 window[t].lx=min(x,X); 48 window[t].ly=min(y,Y); 49 window[t].rx=max(x,X); 50 window[t].ry=max(y,Y); 51 window[t].h=1; 52 siji(i,1,62) {//这里原来打成xiaosiji忘改了 53 if(window[i].h!=0 && i!=t) ++window[i].h; 54 } 55 } 56 void top(char c) { 57 int t=calc(c); 58 int he=window[t].h; 59 window[t].h=1; 60 siji(i,1,62) { 61 if(window[i].h!=0 && window[i].h<he && i!=t) ++window[i].h; 62 } 63 } 64 void del(char c) { 65 int t=calc(c); 66 int he=window[t].h; 67 window[t].h=0; 68 siji(i,1,62) { 69 if(window[i].h!=0 && window[i].h>he) --window[i].h; 70 } 71 } 72 void bottom(char c) { 73 int t=calc(c); 74 int he=window[t].h; 75 window[t].h=cnt; 76 siji(i,1,62) { 77 if(window[i].h!=0 && window[i].h>he && i!=t) --window[i].h; 78 } 79 } 80 int solute(int k,int x1,int y1,int x2,int y2) { 81 if(x2<=x1 || y2<=y1) return 0; 82 int t=k; 83 while(t>0&&(window[cut[t]].rx <=x1 || window[cut[t]].ry<=y1 84 || window[cut[t]].lx>=x2 || window[cut[t]].ly>=y2)) --t; 85 if(t<=0) return (x2-x1)*(y2-y1); 86 87 int res=0; 88 if(window[cut[t]].lx>x1) { 89 res+=solute(t-1,x1,y1,window[cut[t]].lx,y2); 90 } 91 if(window[cut[t]].ly>y1) { 92 res+=solute(t-1,max(x1,window[cut[t]].lx),y1,min(x2,window[cut[t]].rx),window[cut[t]].ly); 93 } 94 if(window[cut[t]].rx<x2) { 95 res+=solute(t-1,window[cut[t]].rx,y1,x2,y2); 96 } 97 if(window[cut[t]].ry<y2) { 98 res+=solute(t-1,max(x1,window[cut[t]].lx),window[cut[t]].ry,min(x2,window[cut[t]].rx),y2); 99 } 100 return res; 101 } 102 void solve() { 103 int x1,y1,x2,y2; 104 while(scanf("%s",a+1)!=EOF) { 105 if(a[1]=='w') { 106 siji(i,4,strlen(a+1)) { 107 if(a[i]<'0' || a[i] > '9') a[i]=' '; 108 } 109 sscanf(a+4,"%d%d%d%d",&x1,&y1,&x2,&y2); 110 ins(x1,y1,x2,y2,a[3]); 111 } 112 else if(a[1]=='t') { 113 top(a[3]); 114 } 115 else if(a[1]=='b') { 116 bottom(a[3]); 117 } 118 else if(a[1]=='d') { 119 del(a[3]); 120 } 121 else { 122 f=0; 123 int t=calc(a[3]); 124 if(window[t].h==0) {puts("0.000");continue;} 125 126 siji(i,1,62) { 127 if(window[t].h>window[i].h && window[i].h!=0) cut[++f]=i; 128 } 129 int sa=solute(f,window[t].lx,window[t].ly,window[t].rx,window[t].ry); 130 int sb=(window[t].ry-window[t].ly)*(window[t].rx-window[t].lx); 131 printf("%.3lf\n",(double)sa/sb*100); 132 } 133 } 134 } 135 int main(int argc, char const *argv[]) 136 { 137 #ifdef ivorysi 138 freopen("window.in","r",stdin); 139 freopen("window.out","w",stdout); 140 #else 141 freopen("f1.in","r",stdin); 142 #endif 143 solve(); 144 return 0; 145 }