51nod 1562 玻璃切割 (STL map+一点点的思考)
来源:互联网 发布:网络脱口秀节目排行榜 编辑:程序博客网 时间:2024/05/01 08:18
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示例
样例输入1
4 3 4
H 2
V 2
V 3
V 1
Output示例
样例输出1
8
4
4
这题我们只有一个需要思考的点,那就是什么切割了多次之后怎样的一块面积最大?
我们可以想到横向最宽,纵向最高的面积一定是最大的。
然后要注意的一点是,横向和纵向处理很容易把人弄晕,
可以先考虑线段的情况,问题变成了,一条线段,切割之后最长的子线段为多少?
求出一个维度之后复制粘贴变成2维的即可。
写起来很绕,需要很强的编码能力,不过这与问题的解决办法已经无关了。
代码:
#include <iostream>#include <algorithm>#include <map>#include <vector>#include <set>#include <math.h>#include <queue> #include <assert.h>#include <stdio.h>#include <stdlib.h>using namespace std;typedef long long ll;#define INF 2147483647//输入 int w, h, n;//mh:高度方向上每个间隔出现的次数。mh[i] = j表示间隔为i的线段有j个。 //mv:宽度方向上每个间隔出现的次数。mv[i] = j表示间隔为i的线段有j个。//h1: h1[i] = j表示高度方向上切割点为i的线段的长度为j。//v1: v1[i] = j表示宽度方向上切割点为i的线段的长度为j。map <int, int> mh, mv, h1, v1;map <int, int>::iterator it, it1;int main() { scanf("%d%d%d", &w, &h, &n); //初始化,长度为h的线段+1,长度为w的线段+1,以0为起点的线段长为h,以0为起点的线段长为w。 mh[h] = 1; mv[w] = 1; h1[0] = h; v1[0] = w; char k1; int k2; while (n--) { getchar(); scanf("%c%d", &k1, &k2); if (k1 == 'H') { //找到切割点前一个点的位置和长度。 it = h1.lower_bound(k2); it--; int con = it->first; int len = it->second; //长度为len的线段-1,如果为0了就从map中删掉 mh[len]--; if (mh[len] == 0) mh.erase(len); //h1: h1[i] = j表示高度方向上切割点为i的线段的长度为j。 h1[con] = k2 - con; h1[k2] = len - h1[con]; //mh:高度方向上每个间隔出现的次数。mh[i] = j表示间隔为i的线段有j个。 mh[h1[k2]]++; mh[h1[con]]++; } else if (k1 == 'V') { it = v1.lower_bound(k2); it--; int con = it->first; int len = it->second; mv[len]--; if (mv[len] == 0) mv.erase(len); v1[con] = k2 - con; v1[k2] = len - v1[con]; mv[v1[k2]]++; mv[v1[con]]++; } //map最后一个值的key最大 it = mh.end(); it--; it1 = mv.end(); it1--; ll p = it->first; ll q = it1->first; printf("%lld\n", p*q); } getchar(); getchar(); return 0;}/*10 10 5H 1H 8H 6H 2H 4*/
- 51nod 1562 玻璃切割 (STL map+一点点的思考)
- 51Nod-1562-玻璃切割
- 51Nod-1562-玻璃切割
- 51nod 1562 玻璃切割
- 51nod-1562:玻璃切割(O(n)模拟)
- 51nod 1562玻璃切割(降维,反向处理)
- 51nod 1562 玻璃切割 (set+离线处理)
- 51Nod 1562 玻璃切割 (set)
- 51nod 1562 玻璃切割 【线段树】
- 51nod 1562 玻璃切割(线段树区间合并)
- STL中map容器的一点点用法
- 玻璃切割
- 三年的一点点思考
- 万事开头难的一点点思考
- 关于人生的一点点思考
- 关于架构的一点点思考
- 51nod1562-模拟&好题&链表|线段树-玻璃切割
- 关于切割绳子的思考
- 51nod 1021 石子归并 (动态规划 简单代码)
- 复杂度
- 作业.设计一个动物声音模拟器(接口)
- 题目68:三点顺序
- 彻底剖析numpy的数据类型
- 51nod 1562 玻璃切割 (STL map+一点点的思考)
- 机器学习笔记
- vim 配置
- 11.19
- 51nod 1649 齐头并进 (djikstra求最短路径,只用跑一次)
- fjnuoj1193 布置会场( 快速幂 矩阵)
- opencv-图像抠图
- TCP/IP网络编程学习之路二
- 剔除重复数据