POJ 2082 Terrible Sets

Terrible Sets
Time Limit: 1000MS   Memory Limit: 30000K
Total Submissions: 2747   Accepted: 1389

Descriptionios

Let N be the set of all natural numbers {0 , 1 , 2 , . . . }, and R be the set of all real numbers. wi, hi for i = 1 . . . n are some elements in N, and w0 = 0. 
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.

Inputapp

The input consists of several test cases. For each case, n is given in a single line, and then followed by n lines, each containing wi and hi separated by a single space. The last line of the input is an single integer -1, indicating the end of input. You may assume that 1 <= n <= 50000 and w 1h 1+w 2h 2+...+w nh n < 10 9.

Outputthis

Simply output Max(S) in a single line for each case.

Sample Inputspa

3
1 2
3 4
1 2
3
3 4
1 2
3 4
-1

Sample Outputcode

12
14
題目大意:給出一系列矩形的寬度和高度,矩形沿着x軸對齊,求這些矩形組成的連續矩形區域的最大面積。
解題方法:這是一道很是好的題,用棧保存矩形,若是高度遞增則不斷入棧,若是遇到當前輸入的比棧頂高度小,則從棧頂開始不斷出棧而且計算最大面積,直到棧頂高度小於當前輸入高度則中止出棧,並把開始出棧矩形的寬度累加獲得totalw,把totalw和當前輸入的矩形寬度相加獲得當前輸入矩形的寬度,併入棧,這樣棧中保存的永遠都是高度遞增的矩形,最後輸入完了以後若是棧不爲空,則依次出棧並計算最大面積。
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stack>
using namespace std;

typedef struct
{
    int w;
    int h;
}Node;

int main()
{
    stack<Node> Stack;
    int totalw, ans, w, h, n;
    while(scanf("%d", &n) != EOF && n != -1)
    {
        ans = 0;
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", &w, &h);
            if (Stack.empty())//若是棧爲空,則入棧
            {
                Node temp;
                temp.w = w;
                temp.h = h;
                Stack.push(temp);
            }
            else
            {
                totalw = 0;
                if (h >= Stack.top().h)//若是當前矩形高度大於棧頂矩形高度,入棧
                {
                    Node temp;
                    temp.w = w;
                    temp.h = h;
                    Stack.push(temp);
                }
                else
                {
                    //若是當前輸入矩形高度小於棧頂矩形高度,出棧並計算最大面積
                    while(!Stack.empty() && Stack.top().h > h)
                    {
                        //寬度從棧頂開始依次累加
                        totalw += Stack.top().w;
                        if (ans < totalw * Stack.top().h)
                        {
                            //獲得最大面積
                            ans = totalw * Stack.top().h;
                        }
                        Stack.pop();
                    }
                    Node temp;
                    //出棧完畢以後,棧爲空或者棧頂矩形高度小於當前輸入高度,
                    //以保證棧中的矩形高度遞增
                    temp.w = w + totalw;//加上開始出棧的全部矩形寬度之和,即爲當前輸入矩形的寬度
                    temp.h = h;
                    Stack.push(temp);
                }
            }
        }
        totalw = 0;
        //若是棧不爲空,則依次出棧並計算最大面積
        while(!Stack.empty())
        {
            totalw += Stack.top().w;
            if (ans < totalw * Stack.top().h)
            {
                ans = totalw * Stack.top().h;
            }
            Stack.pop();
        }
        printf("%d\n", ans);
    }
    return 0; 
}
相關文章
相關標籤/搜索