POJ-2082 terriblesets(堆栈题+阅读理解)
1、关于题面的理解:此题故弄玄虚,题面拗口;实际上不过是求若干连续矩形中的所能构成的最大矩形面积。
2、关于做法:虽然是数据结构题,但这种思维角度值得学习。排序简化+等效转化(还带一点回溯的味道)
ac代码如下:
#include<iostream> #include<cstdlib> #include<stack> using namespace std; struct rec { int w,h; }data; int main(void){ int n; while(scanf("%d",&n)&&n!=-1){ stack<rec> s; int lasth=0,ans=0; while(n--){ scanf("%d%d",&data.w,&data.h); if(data.h<lasth){ /*若违反升序原则,则进行等效转化:找到能使得新输入矩阵满足升序的插入位置。在找的同时计算即将删除的这些矩形所能形成的最大矩形面积。 因为事实上除了此时的元素data外,栈中的排列已经是升序的,因此计算最大的过程非常简单。 */ int totalw=0,curarea=0; while(s.empty()==0&&s.top().h>data.h){ totalw+=s.top().w; curarea=totalw*s.top().h; if(curarea>ans)ans=curarea; s.pop(); } data.w=totalw+data.w; /*此时删除的矩形可以等效 替换成data.w=删除部分的总长度+新输入矩形的w,data.h=新输入矩形的高,压栈即可。 */ s.push(data); } else{//若升序,则直接插入 s.push(data); } lasth=s.top().h; } int totalw=0,curarea=0; while(s.empty()==0){//最后再进行一次遍历 totalw+=s.top().w; curarea=totalw*s.top().h; if(curarea>ans)ans=curarea; s.pop(); } cout<<ans<<endl; } return 0; }