Acdream 1205 Disappeared Block(模拟)

题目链接:传送门

题意:

有n个高度分别为hi的山峰,然后海平面,初始的时候为0,然后每隔一秒还平面会上升一米

然后给定m个时刻,求第i秒时这时候的山峰分成了几块初始的时候都连在一起很明显是一块。

分析:

我们将海面看着是不动的,然后将时间倒着来考虑,考虑山峰是逐渐上升的,然后如果它的

在这个某时刻之前如果它的左右的山峰都没有出现的话那么块数就要增加,否则如果左右都

出现了的话那么块数就要减一。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn  = 1e6+10;

struct nod{
    int id,h;
    bool operator <(const struct nod &tmp)const{
        return h>tmp.h;
    }
}p[maxn];

int s[maxn];
int ans[maxn];
bool vis[maxn];

int main()
{
    int t,n,m,cas=1;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++){
            scanf("%d",&p[i].h);
            p[i].id=i;
        }
        for(int i=0;i<m;i++){
            scanf("%d",&s[i]);
        }
        sort(p,p+n);
        memset(vis,0,sizeof(vis));
        int i,j,high=0;
        for(i=m-1,j=0;i>=0;i--){
            for(;j<n&&s[i]<p[j].h;j++){
                vis[p[j].id]=1;
                if((p[j].id==0||!vis[p[j].id-1])&&(p[j].id==n-1||!vis[p[j].id+1]))//左右两边都没有露数来
                    high++;
                else if((p[j].id>0&&vis[p[j].id-1])&&(p[j].id<n-1&&vis[p[j].id+1]))
                    high--;
            }
            ans[i]=high;
        }
        printf("Case #%d: ",cas++);
        for(int i=0;i<m;i++){
            if(i==m-1) printf("%d\n",ans[i]);
            else printf("%d ",ans[i]);
        }
    }
    return 0;
}


 

你可能感兴趣的:(Acdream 1205 Disappeared Block(模拟))