CodeForces 527C(set大法好)

题目链接:CodeForces 527C


题目大意:

 一块w*h的玻璃 对其进行n次切割 每次切割都是垂直或者水平的 输出每次切割后最大单块玻璃的面积。

第一行输入 w h n , 剩下n行每行一次cut , H 代表水平切, V 代表竖直切。

Input
4 3 4
H 2
V 2
V 3
V 1
Output
8
4
4
2
Input
7 6 5
H 4
V 3
V 5
H 2
V 1
Output
28
16
12
6
4

图形样例


  第一组样例

  第二组样例

思路

可以看出经过n次切割之后,剩余的最大面积就是剩余部分长的最大值 x 宽的最大值。 所以我们用两个multiset储存切割后的长宽即可。

如何计算长宽 ? 每次切,都要寻找切线两边的边界,这样才能计算出新的长或宽,以及删除旧的长或宽。我们用利用set中元素的有序性,再加上find 操作就很容易找到两边的元素了。

 源代码

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
const int maxn = 200000 +10;
int main(){
	int w,h,q;
	set<int>sH;
	set<int>sW;
	multiset<int>mH;
	multiset<int>mW;
	while(scanf("%d%d%d",&w,&h,&q)!=EOF){
		sH.clear();sW.clear();
		mW.clear();mH.clear();
		sH.insert(h);sH.insert(0); //管理边界的set先插入初始的边界
		sW.insert(w);sW.insert(0);
		mH.insert(h);mW.insert(w); //管理长宽的multiset 先插入最大的长宽
		char order;
		int pos;
		while(q--){
			cin>>order>>pos;
			if(order == 'H'){
				sH.insert(pos); //先将切线插入到对应位置
				int a = *(--sH.find(pos)); //找到相邻切线
				int b = *(++sH.find(pos));
				// mH.erase(b-a); //这里注意不能这样 删除 ,否则就将所有元素中等于 b - a 的都删除了。
				mH.erase(mH.find(b-a)); //在multiset中删除旧的长 或 宽。
				// cout<<" "<<pos<<" "<< b<<" "<<a<<endl;
				mH.insert(b-pos); // 插入新的长或宽
				mH.insert(pos-a);
			}
			else{
				sW.insert(pos);
				int a = *(--sW.find(pos));
				int b = *(++sW.find(pos));
				// cout<<" "<<pos<<" "<< b<<" "<<a<<endl; 
				// mW.erase(b-a);
				mW.erase(mW.find(b-a));
				mW.insert(b-pos);
				mW.insert(pos-a);
			}
			printf("%I64d\n",(long long)*(--mW.end()) **(--mH.end())); //结果可能超int
		}
	}
	return 0;
}



转载于:https://www.cnblogs.com/chaiwenjun000/p/5321144.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值