vjudge 上题目链接:Glass Carving
题目大意: 一块 w * h 的玻璃,对其进行 n 次切割,每次切割都是垂直或者水平的,输出每次切割后最大单块玻璃的面积:
用两个 set 存储每次切割的位置,就可以比较方便的把每次切割产生和消失的长宽存下来(用个 hash 映射数组记录下对应值的长宽的数量即可,O(1) 时间维护),每次切割后剩下的最大长宽的积就是答案了:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<set> 5 using namespace std; 6 typedef long long LL; 7 const int N = 200005; 8 9 int w[N], h[N]; // 记录存在的边长的数量 10 set<int> sw, sh; // 记录下所有切点的位置 11 set<int>::iterator i,j; 12 13 void insert(set<int> &s, int *b, int p) { 14 s.insert(p); 15 i = j = s.find(p); 16 ++j; --i; 17 --b[*j - *i]; // 除掉被分开的长宽 18 ++b[p - *i]; // 新产生了两个长宽 19 ++b[*j - p]; 20 } 21 22 int main() { 23 int ww,hh,n,p; 24 while(~scanf("%d %d %d",&ww,&hh,&n)) { 25 sw.clear(); sh.clear(); 26 sw.insert(0); sw.insert(ww); 27 sh.insert(0); sh.insert(hh); 28 29 memset(w, 0, sizeof w); w[ww]++; 30 memset(h, 0, sizeof h); h[hh]++; 31 int y = ww, x = hh; 32 33 while(n--) { 34 getchar(); 35 if(getchar() == 'H') { 36 scanf("%d",&p); 37 insert(sh, h, p); 38 } 39 else { 40 scanf("%d",&p); 41 insert(sw, w, p); 42 } 43 while(!w[y]) --y; // 因为每次切割后最大值总是单调递减的,所以这样维护即可,如果从头到尾扫一遍的话会超时的
44 while(!h[x]) --x; 45 printf("%I64d ", (LL)x * y); 46 } 47 } 48 return 0; 49 }
参考了别人的思路才会做的,果然好强大,自己也好弱 Orz 。。。