Codeforces 527C Glass Carving

  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\n", (LL)x * y);
46         }
47     }
48     return 0;
49 }

  参考了别人的思路才会做的,果然好强大,自己也好弱 Orz 。。。

posted @ 2015-09-18 10:44  Newdawn_ALM  阅读(172)  评论(0编辑  收藏  举报