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;
}

 

posted @ 2018-04-04 20:24  KYSpring  阅读(130)  评论(0编辑  收藏  举报