51nod 1562玻璃切割(降维,反向处理)
来源:互联网 发布:魔卡幻想 淘宝号 编辑:程序博客网 时间:2024/05/01 06:12
1562 玻璃切割
题目来源: CodeForces
基准时间限制:1.5 秒 空间限制:131072 KB 分值: 20 难度:3级算法题
收藏
关注
现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。
切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
样例解释:
对于第四次切割,下面四块玻璃的面积是一样大的。都是2。
Input
单组测试数据。第一行有三个整数 w,h,n (2≤w,h≤200000, 1≤n≤200000),表示玻璃在横向上长w 毫米,纵向上长h 毫米,接下来有n次的切割。接下来有n行输入,每一行描述一次切割。输入的格式是H y 或 V x。H y表示横向切割,切割线距离下边缘y毫米(1≤y≤h-1)。V x表示纵向切割,切割线距离左边缘x毫米(1≤x≤w-1)。输入保证不会有两次切割是一样的。
Output
对于每一次切割,输出所有玻璃中面积最大的是多少。
Input示例
样例输入14 3 4H 2V 2V 3V 1
Output示例
样例输出18442
System Message (题目提供者)
题解:首先进行降维处理,因为直接去考虑矩阵的面积比较麻烦,转而去考虑每一条边的切割后的最大边,在横向和纵向上分别取最大值然后就是答案了。
其次,为了使得题目变得更简单,我们可以考虑反向进行处理询问,也就是先把所有的切割加进去,然后转而去删掉切割边。这样做的好处是,可以把最大值的更新优化到O(1).如果正向的话,恐怕只能在遍历一遍了。
最后,实现的过程有点技巧吧。我这里也是看了大佬的博客借鉴了方法。由于数据量的原因,我们需要保证查询最大值和修改切割边的操作都优化到O(1),才能不超时。其实就是传统的思路,空间换时间。用一个结构体存每一个点的前一个点和后一个点还有和前一个点的差值。然后开一个20万的数组,这样可以保证在O(1)的时间内,索引到删除边的位置,进行维护。具体这里的实现还是看代码吧。
代码:
#include<bits/stdc++.h>#include<iostream>#include<cstring>#include<math.h>#include<stdlib.h>#include<cstring>#include<cstdio>#include<utility>#include<algorithm>#include<map>#include<stack>#include<set>#include<queue>using namespace std;typedef long long ll;const int maxn = 2*1e5+5;const int mod = 1e9+7;const int Hash = 10000;const int INF = 1<<30;const ll llINF = 1e18+999;int w,m,n;//切割线的左边和右边两条边的位置,切割线距离左边割线的距离struct cutting{ ll left, right, length;};cutting H[maxn], V[maxn];ll ans[maxn], h[maxn], v[maxn];pair<char, int> ins[maxn];int main( ){ //freopen("input.txt", "r", stdin); scanf("%d%d%d", &w,&m,&n); ll hmax = 0, vmax = 0; h[0] = v[0] = h[m] = v[w] = 1; for(int i=0; i<n; i++) { getchar( ); scanf("%c%d", &ins[i].first, &ins[i].second); if(ins[i].first == 'H') h[ins[i].second] = 1; else v[ins[i].second] = 1; } int pre = 0; for(int i=1; i<=m; i++) { //pre前一个割点,i当前割点 if(h[i] == 1) { H[i].left = pre; H[i].length = i-pre; H[pre].right = i; hmax = max(hmax, H[i].length); pre = i; } } pre = 0; for(int i=1; i<=w; i++) { //pre前一个割点,i当前割点 if(v[i] == 1) { V[i].left = pre; V[i].length = i-pre; V[pre].right = i; vmax = max(vmax, V[i].length); pre = i; } } for(int i=n-1; i>-1; i--) { ans[i] = hmax*vmax; int cur = ins[i].second;//当前的割点 if(ins[i].first == 'H') { H[H[cur].left].right = H[cur].right; H[H[cur].right].left = H[cur].left; H[H[cur].right].length += H[cur].length; hmax = max(hmax, H[H[cur].right].length); } else { V[V[cur].left].right = V[cur].right; V[V[cur].right].left = V[cur].left; V[V[cur].right].length += V[cur].length; vmax = max(vmax, V[V[cur].right].length); } } for(int i=0; i<n; i++) printf("%lld\n", ans[i]); return 0;}
算法者,贵在积累,深入浅出。
阅读全文
0 0
- 51nod 1562玻璃切割(降维,反向处理)
- 51nod 1562 玻璃切割 (set+离线处理)
- 51Nod-1562-玻璃切割
- 51Nod-1562-玻璃切割
- 51nod 1562 玻璃切割
- 51nod-1562:玻璃切割(O(n)模拟)
- 51Nod 1562 玻璃切割 (set)
- 51nod 1562 玻璃切割 【线段树】
- 51nod 1562 玻璃切割(线段树区间合并)
- 51nod 1562 玻璃切割 (STL map+一点点的思考)
- 玻璃切割
- 51nod1562-模拟&好题&链表|线段树-玻璃切割
- python 切词算法(正向切割、反向切割)
- 51 nod 1306 高楼和棋子(反向思考的DP)@
- 51nod 1276 【离线处理】
- 字符串的切割处理
- 图像处理 图像切割
- 图像处理之玻璃水印特效(祝大家圣诞节快乐)
- 大型互联网b2b b2c o2o电子商务云平台
- 避免多次点击PerfectClickListener
- python使用ip代理池,测试ip是否有用
- 自定义一个List排序规则,然后对另一个List按照该规则排序
- sslsocket实例
- 51nod 1562玻璃切割(降维,反向处理)
- Spring Cloud还是Dubbo
- VMware如何监测性能问题
- ArcGIS Administartor localhost是无效主机名
- ROSbridge:为你的机器人构建WEB图形用户界面
- 微服务架构的基础框架选择:Spring Cloud还是Dubbo
- 实现图片还原,当前点击的显示当前指定图片
- AngularJs模糊查询和修改密码
- html数据传到mysql简单例子