16. 看楼房

小张在暑假时间进行了暑期社会调查。调查的内容是楼房的颜色如何影响人们的心情。于是他找到了一个楼房从左到右排成一排的小区,这个小区一共有n栋楼房,每个楼房有一个颜色和一个高度。小张调查的内容为每次他站在第栋楼和第栋楼之间向左看,他记录下此时他看到的楼房颜色数作为他的调查结果。由于小张在暑假时间沉迷游戏来不及做实地调查,只好拜托你将调查结果告诉他。

 

 

解题思路:

题意要求站在i和i+1中间向左看,低的楼会被高的楼挡住,高的楼会露出颜色。

我们考察两个相邻的元素,如果左面比右面低,那么站在右面的楼的右面看,无论如何也看不到左面的楼,不会作为答案输出,因此我们可以将它舍弃,故保留下来的楼一定是单调递减的。

我们发现这个刚好属于单调栈的性质,因此从左到右遍历,每次统计单调栈中有多少中颜色,输出即可。

统计颜色的方法:记录一个颜色数组和当前有多少颜色 c,当单调栈中删除颜色时,若删除它导致颜色数组中对应的值等于零,则c减去一

代码:

#include<iostream>  
#include<cstring>  
using namespace std;  
pair< int,int >st[1001010];  
pair<int,int>a[1001010];  
int v[1001010];  
int tt;  
int main(){  
    int t;  
    cin>>t;  
    while(t--){  
        int ans=0;  
        tt=0;  
        int n;  
        scanf("%d",&n);  
          
        for(int i=0;i<=n;i++)st[i].first=0,st[i].second=0;  
        for(int i=1;i<=n;i++)scanf("%d",&a[i].second);  //颜色
        for(int i=1;i<=n;i++) scanf("%d",&a[i].first); //高度
        for(int i=1;i<=n;i++)  
    {  
        int x,y;  
        x=a[i].first;//gaodu  
        y=a[i].second;//yanse  
        while (tt && st[tt].first <= x) {  
          
        v[st[tt].second]--;  
        if(v[st[tt].second]==0)ans--;  
        tt -- ;   
        }  
        st[ ++ tt] = {x,y};  
        if(v[y]==0)ans++;  
        v[y]++;  
         printf("%d", ans);  
         if(i<n)printf(" ");  
    }  
    for(int i=0;i<=n;i++)v[st[i].second]=0;  
    puts("");     
    }  
}   

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值