题目大意:
若干矩形相互紧挨着在一条轴线上排成一排,求这些矩形所覆盖的区域中面积最大的矩形,输出其面积。
!!!和POJ 2559类同(只不过其每个矩形的底边长都是1)。
其中,矩形数不超过50000,所有矩形面积之和不超过10^9,多个测例(题中给出数目),以矩形个数为-1结束测例退出程序。
STL stack:
注释代码:
/*
* Problem ID : POJ 2082 Terrible Sets
* Author : Lirx.t.Una
* Language : G++
* Run Time : 110 ms
* Run Memory : 716 KB
*/
#pragma G++ optimize("O2")
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
struct Rec {//Rectangle,矩形
int w;//width,宽
int h;//height,长
};
int
main() {
int n;//矩形个数
int i;//计数变量
int w_tmp;//temporary width,宽度临时变量
int s_tmp;//面积临时变量
int ans;//answer,最终结果
Rec rec;//临时矩形,用于接收输入的矩形
stack<Rec> stk;//stack,存放矩形的栈
while ( scanf("%d", &n), n != -1 ) {
ans = 0;//在每个测例的开始都将结果初始化
for ( i = 1; i <= n; i++ ) {
scanf("%d%d", &rec.w, &rec.h);
//保持栈中的矩形高度递增
//若待入栈的矩形高度不满足入栈后高度递增的要求则需要
//将前面高度比它大的矩形一个个削得跟它一样大
//最后再将它们合并成一个矩形
//每削一个矩形都需要记录一下该矩形的面积,将比ans大的面积
//更新给ans,削完后再跟前面的矩形合并成一个矩形
//待削到满足递增要求后再将经过一系列合并后的矩形和
//待入栈的矩形合并成一个矩形后入栈
w_tmp = 0;//初始化
while ( !stk.empty() && rec.h <= stk.top().h ) {
//栈非空且入栈矩形高度过低,则需要削前面矩形的头
w_tmp += stk.top().w;//和前一个矩形合并(底边相加)
s_tmp = w_tmp * stk.top().h;//高度统一(和前面较矮的看齐)
if ( s_tmp > ans )
ans = s_tmp;//动态更新
stk.pop();//合并后将前一个弹栈,再检查更前面的一个矩形
}
//削完后和待入栈的矮矩形合并后入栈
rec.w += w_tmp;//底边相加,高度和入栈矩形看齐
stk.push(rec);//合并后压栈
}
//所有矩形不管削头合并过还是没有削头合并过都已经全部入栈了
//现在就用上面用过的方法逐一对高度递增的矩形序列削头合并
//动态更新ans后就可以得到最大的面积值了
w_tmp = 0;
while ( !stk.empty() ) {
w_tmp += stk.top().w;
s_tmp = w_tmp * stk.top().h;
if ( s_tmp > ans )
ans = s_tmp;
stk.pop();
}
printf("%d\n", ans);
}
return 0;
}
无注释代码:
#pragma G++ optimize("O2")
#include <iostream>
#include <cstdio>
#include <stack>
using namespace std;
struct Rec {
int w;
int h;
};
int
main() {
int n;
int i;
int w_tmp;
int s_tmp;
int ans;
Rec rec;
stack<Rec> stk;
while ( scanf("%d", &n), n != -1 ) {
ans = 0;
for ( i = 1; i <= n; i++ ) {
scanf("%d%d", &rec.w, &rec.h);
w_tmp = 0;
while ( !stk.empty() && rec.h <= stk.top().h ) {
w_tmp += stk.top().w;
s_tmp = w_tmp * stk.top().h;
if ( s_tmp > ans )
ans = s_tmp;
stk.pop();
}
rec.w += w_tmp;
stk.push(rec);
}
w_tmp = 0;
while ( !stk.empty() ) {
w_tmp += stk.top().w;
s_tmp = w_tmp * stk.top().h;
if ( s_tmp > ans )
ans = s_tmp;
stk.pop();
}
printf("%d\n", ans);
}
return 0;
}
C语言实现栈:
/*
* Problem ID : POJ 2082 Terrible Sets
* Author : Lirx.t.Una
* Language : C
* Run Time : 110 ms
* Run Memory : 176 KB
*/
#include <stdio.h>
#define MAXSTACKSIZE 50000
typedef struct {
int w;
int h;
} Rec;
Rec stk[MAXSTACKSIZE];
int
main() {
int n;
int i;
int w_tmp;
int s_tmp;
int ans;
int top;
Rec rec;
while ( scanf("%d", &n), n != -1 ) {
ans = 0;
top = -1;
for ( i = 1; i <= n; i++ ) {
scanf("%d%d", &rec.w, &rec.h);
w_tmp = 0;
while ( top > -1 && rec.h <= stk[top].h ) {
w_tmp += stk[top].w;
s_tmp = w_tmp * stk[top].h;
if ( s_tmp > ans )
ans = s_tmp;
top--;
}
top++;
stk[top].w = rec.w + w_tmp;
stk[top].h = rec.h;
}
w_tmp = 0;
while ( top > -1 ) {
w_tmp += stk[top].w;
s_tmp = w_tmp * stk[top].h;
if ( s_tmp > ans )
ans = s_tmp;
top--;
}
printf("%d\n", ans);
}
return 0;
}