[CodeForces522B] Photo to Remember

Posted zhenglw

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CodeForces522B] Photo to Remember相关的知识,希望对你有一定的参考价值。

某一天,n个朋友在一起聚会,他们已经很久没见了,于是他们决定拍照留念。

简单的说,拍照的时候,每个人有一个高度和宽度,第i个的高度和宽度分别是hi和wi。这些人排成一条直线,照片的最小的面积必须包含所有的的人,所以照片的面积是W*H,W是所有人的宽度之和,H是所有人中高度最高的那个人的高度。现在想要知道当第i个人不在照片中的时候,照片的最小面积是多少。

输入

第一行是一个正整数N,表示人的数量。

接下来N行,每行两个整数wi和hi,分别表示每个人的宽度和高度。

数据范围:2<=N<=200000,1<=wi<=10,1<=hi<=1000。

输出

包含b1,b2,b3。。Bn,bi表示第i个人不在照片中的时候,照片的最小面积。

输入输出样例
输入样例#1:
3
1 10
5 5
10 1
输出样例#1:
75 110 60
输入样例#2:
3
2 1
1 2
2 1
输出样例#2:
6 4 6

【思路1】

利用前缀和记录W 1~i的和 sum[i];
利用前后缀数组分别记录1~i(1≤i≤n)的最大值max1[i] 和i~1(1≤i≤n)的最大值max2[i];
处理第i个人时:W为 sum[n]-sum[i]+sum[i-1],H为max(max1[i-1],max2[i+1]);
相乘即可得出面积

代码:

#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
inline int read()
{
    char chr=getchar();
    int f=1,ans=0;
    while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
    while(isdigit(chr))  {ans=ans*10;ans+=chr-'0';chr=getchar();}
    return ans*f;

}
int n,w[200005] ,h[200005],sumw[200005],max1[200005],max2[200005];
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
        w[i]=read(),h[i]=read(),sumw[i]=sumw[i-1]+w[i];//前缀和
    for(int i=1;i<=n;i++)//1~i最大值
        max1[i]=max(max1[i-1],h[i]);
    for(int i=n;i>=1;i--)n~i最大值
        max2[i]=max(max2[i+1],h[i]);
    for(int i=1;i<=n;i++)
    {
        int W=sumw[n]-sumw[i]+sumw[i-1];
        int H=max(max1[i-1],max2[i+1]);//在左右两个区间分别取最大值;
        printf("%d ",W*H);
    }
    return 0;
}

【思路2】

由于每次只有一个人出列,那么对于每个人来说,如果他是最高的,那么H就要取次高的,如果不是次高的,那么H就要取最高的,既然这样,只要记录最大值和次大值便可求出答案;

代码

#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
inline int read()
{
    char chr=getchar();
    int f=1,ans=0;
    while(!isdigit(chr)) {if(chr=='-') f=-1;chr=getchar();}
    while(isdigit(chr))  {ans=ans*10;ans+=chr-'0';chr=getchar();}
    return ans*f;

}
int n,w[200005] ,h[200005],sumw[200005],pos,max1=INT_MIN,max2=INT_MIN;
int main()
{
    n=read();
    for(int i=1;i<=n;i++)
    {
        w[i]=read(),h[i]=read(),sumw[i]=sumw[i-1]+w[i];
        if(max1<h[i])
        pos=i,max1=h[i];
    }
    for(int i=1;i<=n;i++)
    if(i!=pos)
        max2=max(max2,h[i]);
    for(int i=1;i<=n;i++)
    {
        int W=sumw[n]-sumw[i]+sumw[i-1];
        int H;
        if(h[i]==max1) H=max2;
        else H=max1;
        printf("%d ",W*H);
    }
    return 0;
}

以上是关于[CodeForces522B] Photo to Remember的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces - 1484E Skyline Photo(dp+单调栈)

CodeForces - 1013C C - Photo of The Sky 贪心

Codeforces Round #500 (Div. 2) C Photo of The Sky

1013 C. Photo of The Sky

codeforces 868A Bark to Unlock

Codeforces 868A Bark to Unlock