Time Limit: 1000MS | Memory Limit: 30000K | |
Total Submissions: 2999 | Accepted: 1549 |
Description
Define set B = {< x, y > | x, y ∈ R and there exists an index i > 0 such that 0 <= y <= hi ,∑ 0<=j<=i-1wj <= x <= ∑ 0<=j<=iwj}
Again, define set S = {A| A = WH for some W , H ∈ R + and there exists x0, y0 in N such that the set T = { < x , y > | x, y ∈ R and x0 <= x <= x0 +W and y0 <= y <= y0 + H} is contained in set B}.
Your mission now. What is Max(S)?
Wow, it looks like a terrible problem. Problems that appear to be terrible are sometimes actually easy.
But for this one, believe me, it's difficult.
Input
Output
Sample Input
3 1 2 3 4 1 2 3 3 4 1 2 3 4 -1
Sample Output
12 14
Source
最近几天出去玩去了,都没做题,也没发博客了,今天做题感觉也没什么状态了。。做题状态还是要保持好啊,所以今天就对一些基本的数据结构练习一些,对STL不怎么熟悉,就练习一些STL,找找状态,栈的基本操作还是要搞懂!!
参考《ACM/ICPC算法训练教程上的代码》,思路讲解可以看看http://www.cnblogs.com/hxsyl/archive/2012/08/16/2643015.html
题意就是给你一些紧贴着x轴的相互挨着的矩形,给定每个矩形的长宽,问他们可以形成的最大的矩形是多少?
大概的思路就是,用栈来做,如果矩形的高度是递增的,就让它入栈,如果即将入栈的高度小于栈顶元素的高度,就出栈,退到保持递增,在出栈的过程中统计到递增的可以达到的高度的最大面积,记录矩形的总长度。
每次读入一个矩形,若它比栈顶元素还高就直接进栈,否则不断将栈中元素弹栈,直到当前栈顶元素能够与读入的矩形满足高度递增。
弹栈过程中累加弹出的元素的宽度,然后每弹出一个就判断当前弹出元素的高度x
累加的宽度能否更新最大面积ans。然后以新的矩形作高,
已经弹出栈的元素总宽度加上新矩形宽度作宽,把这个矩形插入到栈里。
最终栈肯定是一个单调的,只需要再把栈一个个弹空,弹栈过程中仍像上面那样计算即可。
下面是ac的代码:
#include <iostream>
#include <stack>
#include <cstdio>
using namespace std;
struct rectangle //矩形的结构体
{
int h;
int w;
}data;
int main()
{
int n,ans,prior_h,total_w,area;
while(scanf("%d",&n)&&n!=-1)
{
ans=0;
stack<rectangle>s; //定义一个空栈
prior_h=0; //上次进栈的矩形高度
for(int i=0;i<n;i++)
{
scanf("%d%d",&data.w,&data.h);
if(data.h>prior_h)
{
s.push(data);
}
else
{
total_w=0; //总宽度
area=0; //当前面积
while(!s.empty()&&s.top().h>data.h)
{
total_w+=s.top().w;
area=total_w*s.top().h;
if(area>ans)
ans=area;
s.pop();
}
total_w+=data.w;
data.w=total_w;
s.push(data); //新矩形进栈
}
prior_h=data.h;
}
total_w=0;
area=0;
while(!s.empty())
{
total_w+=s.top().w;
area=total_w*s.top().h;
if(area>ans)
ans=area;
s.pop();
}
printf("%d\n",ans);
}
return 0;
}