1. 程式人生 > >POJ-2082 terriblesets(堆棧題+閱讀理解)

POJ-2082 terriblesets(堆棧題+閱讀理解)

else %d eset 因此 int namespace 遍歷 壓棧 直接

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

POJ-2082 terriblesets(堆棧題+閱讀理解)