题解 P5019 【铺设道路】

· · 题解

思路一:

一看题就知道是模拟题,直接模拟每层填土的过程。

如图所示,一共需填9次土,可以直接用for语句循环判断需填土区块的数量。

代码实现:

#include<iostream>
#include<cstdio>
int n,maxn=0,ans=0;
int h[100000]={0};
int max(int x,int y)
{
    if(x>y)
    {
        return x;
    }
    else
    {
        return y;
    }
}

int main()
{
    scanf("%d",&n);
    for(int a=1;a<=n;a++)
    {
        scanf("%d",&h[a]);
        maxn=max(h[a],maxn);
    }
    for(int a=1;a<=maxn;a++)
    {
        for(int b=1;b<=n+1;b++)
        {
            if(h[b]<a&&h[b-1]>=a)
            {
                ans++;
            }
        }
    }
    printf("%d",ans);
    return 0;
}

可惜这种方法只能拿80分的点,其他TLE。

思路2:

画图后发现,相邻的两部分所需填土的步数等于较高一部分的深度值(图中即3步)

若部分1深度>部分2深度,就有步数=部分1深度

若部分2深度>部分1深度,就有步数=部分2深度

所以不难推出(部分0深度=0):

当当前部分深度<前一部分深度,总步数不变

当当前部分深度>前一部分深度,总步数=总步数+当前部分深度-前一部分深度

代码实现:

#include<iostream>
#include<cstdio>
using namespace std;
int n,ans=0,l=0;
int main()
{
    scanf("%d",&n);
    for(int a=1;a<=n;a++)
    {
        int p;
        scanf("%d",&p);
        if(p>l)
        {
            ans=ans+p-l;
        }
        l=p;
    }
    printf("%d\n",ans);
}

经过测试,此思路可以轻松拿下所有点,仅耗时33ms