【BIT2021程设】17.看楼房——经典栈

写在前面:

本系列博客仅作为本人十一假期过于无聊的产物,对小学期的程序设计作业进行一个总结式的回顾,如果将来有BIT的学弟学妹们在百度搜思路时翻到了这一条博客,也希望它能对你产生一点帮助(当然,依经验来看,每年的题目也会有些许的不同,所以不能保证每一题都覆盖到,还请见谅)。

不过本人由于学艺不精,代码定有许多不足之处,欢迎各位一同来探讨。

同时请未来浏览这条博客的学弟学妹们注意,对于我给出完整代码的这些题,仅作帮助大家理解思路所用(当然,因为懒,所以大部分题我都只给一个伪代码)。Anyway,请勿直接复制黏贴代码,小学期的作业也是要查重的,一旦被查到代码重复会严厉扣分,最好的方法是浏览一遍代码并且掌握相关的要领后自己手打一遍,同时也要做好总结和回顾的工作,这样才能高效地提升自己的代码水平。

加油!


成绩10开启时间2021年09月3日 星期五 11:00
折扣0.8折扣时间2021年09月9日 星期四 23:00
允许迟交关闭时间2021年10月10日 星期日 23:00

Description

小张在暑假时间进行了暑期社会调查。调查的内容是楼房的颜色如何影响人们的心情。于是他找到了一个楼房从左到右排成一排的小区,这个小区一共有n栋楼房,每个楼房有一个颜色c_i和一个高度h_i。小张调查的内容为每次他站在第i栋楼和第i+1栋楼之间向左看,他记录下此时他看到的楼房颜色数作为他的调查结果。

由于小张在暑假时间沉迷游戏来不及做实地调查,只好拜托你将调查结果告诉他。

Input

本题有多组数据。

每组数据第一行一个整数n。表示有n栋楼房从左到右排成一排。

第二行n个数,表示每个楼房的颜色(1 \leq c_i \leq 10^6 )

第三行n个数,表示每个楼房的高度(1 \leq c_i \leq 10^9 )

数据保证所有组数据的\sum{n} \leq 1000000

Output

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

Notes

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

测试用例 1以文本方式显示
  1. 2↵
  2. 5↵
  3. 1 2 3 4 5↵
  4. 1 3 4 2 5↵
  5. 5↵
  6. 1 2 4 4 5↵
  7. 1 3 4 2 5↵
以文本方式显示
  1. 1 1 1 2 1↵
  2. 1 1 1 1 1↵
1秒64M0


题意分析:

        既然要动态地输出看到的景象,而眼睛优先看到的肯定是最近的——也就是最后一个输入的。这不就是“后进先出LIFO”吗,不用想了,肯定是栈(名词解释:栈)。

        其次呢,楼房本质上又是一个二元组,所以很自然的想到以二元组为元素的栈。

        再然后呢,因为我们能看到的楼房肯定是远高近低,所以这又是一个以前提到过的单调栈。

        于是,整体的思路就非常简单了。每换一个位置,就考虑让新的楼房入栈,入栈前,弹出所有楼房高度没有新楼高的元素直到栈中全是比新楼更高的或者栈空,然后更新一下颜色数量即可。唯一的难点在于如何处理同色不同高的楼,我这里的方法是用一个查找表(map或者hashmap)来存储颜色的种类-颜色的数量这个键值对,如果某个楼房出栈,对应的值减一,如果减为零则删除这个键。这样只要统计键的数量就可以知道总的颜色数量了,也许有更好的办法但我没想到T^T,反正这样已经足够AC了。


伪代码:

读入数据组数T,一个长度为T的循环:

        初始化栈,初始化颜色表;

        长度为n的循环:

                用一个二元组保存新楼相关参数;

                循环条件:栈非空且栈顶楼房高度\leq新楼高度

                        不断弹出栈顶;

                        更新颜色表,对应值减一,如果减为0则删除键;

                新楼入栈;

                更新颜色表,对应值加一;

                输出当前颜色数;

        输出回车;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

千里之码

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

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

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

打赏作者

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

抵扣说明:

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

余额充值