Acdream 1205 Disappeared Block(模擬)

bigbigship發表於2015-07-01

題目連結:傳送門

題意:

有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;
}