看楼房题目

题目信息

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

输入

本题有多组数据。
每组数据第一行一个整数 n 。表示有 n 栋楼房从左到右排成一排。
第二行 n 个数,表示每个楼房的颜色 (1 ≤ c ≤ 10^6 )
第三行 n 个数,表示每个楼房的高度 (1 ≤ c ≤ 10^9 )
数据保证所有组数据的 n ≤ 1000000

输出

每组数据输出 n 个数,第 i 个数表示他站在第 i 栋楼和第 i+1 栋楼之间向左看,能够看到的楼房颜色数。

提示

在从左向右看楼房的时候,左边较矮的楼房会被右边较高的楼房挡住。

测试样例

2
5
1 2 3 4 5
1 3 4 2 5
5
1 2 4 4 5
1 3 4 2 5
1 1 1 2 1
1 1 1 1 1

解答

#include <cstring>
#include <iostream>
#include <stack>

using namespace std;

struct Structure
{
public:
    int color;
    int hight;
};

int main()
{
    //ios::sync_with_stdio(false);
    //freopen("E://test.txt", "r", stdin);
    //freopen("E://out.txt", "w", stdout);
    int T;
    scanf("%d", &T);
    while (T--)
    {
        int n;
        scanf("%d", &n);

        int structures[1000005];//存储下第一次输入进去的楼房颜色
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &structures[i]);
        }

        stack<Structure> s;//维护一个栈,用来考量楼房
        int colors[1000005] = { 0 };//维护一个colors用来表示之前是否有此颜色的
        int Count = 0;

        for (int i = 0; i < n; i++)
        {
            Structure tmp;
            scanf("%d", &tmp.hight);
            tmp.color = structures[i];
            if (s.empty()|| tmp.hight < s.top().hight)
            {//如果是空的直接压入
                s.push(tmp);
                if (colors[tmp.color] == 0)
                    Count++;
                colors[tmp.color]++;//此处拥有此颜色,给他添加上
            }
            else
            {//如果此时输入的楼房高度大于等于之前的楼房,那么之前的楼房就看不见了,所以删除之前的矮子们
                while (tmp.hight >= s.top().hight)
                {
                    colors[s.top().color]--;
                    if (colors[s.top().color] == 0)
                        Count--;
                    s.pop();

                    if (s.empty()|| tmp.hight < s.top().hight)
                    {
                        s.push(tmp);
                        if (colors[tmp.color] == 0)
                            Count++;
                        colors[tmp.color]++;
                        break;
                    }
                }
            }

            printf("%d", Count);
            if (i < n - 1)
            {
                printf(" ");
            }
        }
        printf("\n");
    }
    return 0;
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zhj12399

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值