问题链接:http://codeforces.com/contest/528/problem/A
题意:
现在有一块玻璃,是长方形的(w 毫米× h 毫米),现在要对他进行切割。
切割的方向有两种,横向和纵向。每一次切割之后就会有若干块玻璃被分成两块更小的玻璃。在切割之后玻璃不会被移动。
现在想知道每次切割之后面积最大的一块玻璃是多少。
简单set应用,每次分别把横、纵切割的位置存入相应的容器,然后把横纵相对位置存入另外的两个容器;
每切割一次,存相对位置的容器里就要添加两个相对位置,并删除受影响的相对位置,然后每次找两个相
对位置容器里的最大值相乘即可
set的应用:
调用头文件:
#include<set>
using namespace std;
详细用法(部分):
set<int> t ------ 定义一个int类型的容器,注意set里的每个元素只会出现1次
t.insert(k) ------ 插入元素k,多次插入同一个元素后面无效
t.count(k) ------ 判断元素k是否在容器内
t.erase(k) ------ 删除元素k,若不存在则删除无效
t.clear() ------ 清空容器
t.size() ------ 返回容器现有元素个数
t.empty() ------ 判断容器是否为空
想遍历set里的元素或进行进一步修改,必须定义对应迭代器,以下三种定义方法(迭代器类似于指针)
set<int>::iterator it ------ 定义正向迭代器
set<int>::reverse_iterator rit; ------ 定义反向迭代器
auto it = t.begin(); ------ 因为t.begin()返回正向迭代器,所以it自动被定义为正向迭代器,可适应其他所有操作
以下需要迭代器的操作:
t.begin() ------ 返回set中第一个元素,类型为正向迭代器
t.rbegin() ------ 返回set中最后一个元素,类型为反向迭代器
t.end() ------ 返回set中最后一个元素,类型为正向迭代器
t.rend() ------ 返回set中第一个元素,类型为反向迭代器
t.find(k) ------ 寻找k,若找到返回对应的迭代器,否则返回end();
t.insert(a, b) ------ 插入指针[a, b)之间的元素,已有元素不会再次插入
t.erase(it) ------ 删除迭代器it对应的元素
t.erase(l, r) ------ 删除迭代器[l, r)之间的元素
lower_bound(k) ------ 返回第一个大于等于k的元素的迭代器
upper_bound(k) ------ 返回第一个大于k的元素的迭代器
#include<set>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define maxn 200005
typedef long long ll;
ll a[maxn],b[maxn];
set<ll>t1,t2;
multiset<ll>d1,d2;//与set的唯一区别是该容器内允许存在重复元素
int main(void)
{
char c;
ll w,h,n,i,t;
multiset<ll>::iterator it;
scanf("%lld%lld%lld",&w,&h,&n);
t1.insert(w);t1.insert(0);
t2.insert(h);t2.insert(0);
d1.insert(w);d2.insert(h);
for(i=1;i<=n;i++)
{
scanf(" %c%lld",&c,&t);
if(c=='V')
{
it=t1.lower_bound(t);
ll p1=*it;
it--;
ll p2=*it;
it=d1.find(p1-p2);
d1.erase(it);
d1.insert(p1-t);
d1.insert(t-p2);
t1.insert(t);
}
else
{
it=t2.lower_bound(t);
ll p1=*it;
it--;
ll p2=*it;
it=d2.find(p1-p2);
d2.erase(it);
d2.insert(p1-t);
d2.insert(t-p2);
t2.insert(t);
}
ll maxx=*(d1.rbegin());
ll maxy=*(d2.rbegin());
printf("%lld\n",maxx*maxy);
}
return 0;
}