codeforces #296 div2 (527C) STL中set的运用
Posted lytwajue
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces #296 div2 (527C) STL中set的运用相关的知识,希望对你有一定的参考价值。
题意:在一块H*M的玻璃上每次划一刀(仅仅能水平或竖直)。输出每次划开之后剩下的玻璃中面积最大的一块的面积。
做题的时候。觉得这么大的数据量,有每次查询输出,应该是数据结构的内容。
这道题能够用STL中的set容器来非常好地解决~set容器其本身就是用红黑树这样的数据结构来实现的。所以和原来的推測并不相悖。STL平时用的并不多。里面的一些函数非常生疏,熟悉一下
解题思路:
首先建立两个set型容器 ,每次分割都将分割的位置h或w插入到set中,因为set可以自己主动排序。运用两个函数lower_bound()和upper_bound()就行找到 和所插入的位置 前后相邻的两个已经被分割的位置,从而得到此次分割后新增的两个空间(见代码);
在建立两个set容器用来存最长的水平距离和最长的竖直距离,每次在插入两个新的距离元素的时候同一时候删除掉之前的大的距离元素。
另外。关于lower_bound()和upper_bound()函数:
关于rbegin() 和rend()
rbegin() 返回的是反转set之后第一个元素的位置,也就是说*rbegin() = set中最大的元素;
rend()同理。
他们的迭代器是:
multiset<int>::reverse_iterator
rit;
code:
#include <bits/stdc++.h> using namespace std; typedef long long ll; int main() { int W, H, N; cin >> W >> H >> N; set<int> h, w; multiset<int> mh, mw; h.insert(H); h.insert(0); w.insert(W); w.insert(0); mh.insert(H); mw.insert(W); set<int>::iterator l, r; while (N--) { char c; int x; scanf(" %c %d", &c, &x); if (c == ‘H‘) { l = h.lower_bound(x);///找到第一个 >= x的位置 r = l; l--;///迭代器向左移一个 h.insert(x);///插入新的分割线 mh.insert((*r)-x);///添加新的距离元素 mh.insert(x-(*l));///添加新的距离元素 mh.erase(mh.find((*r)-(*l)));///删除旧的距离元素 } else { ///以下凝视同上 l = w.lower_bound(x); r = l; l--; w.insert(x); mw.insert((*r)-x); mw.insert(x-(*l)); mw.erase(mw.find((*r)-(*l))); } ///用最大的水平长度 * 最大的竖直长度 = 最大面积 ll ans = ((ll)(*mh.rbegin()) * (*mw.rbegin())); printf("%lld\n", ans); } return 0; }
以上是关于codeforces #296 div2 (527C) STL中set的运用的主要内容,如果未能解决你的问题,请参考以下文章
Error Correct System CodeForces - 527B
Codeforces Round #296 (Div. 2) C. Glass Carving(想法题)
Codeforces 527C Glass Carving (最长连续0变形+线段树)