看楼房 | C++ | 栈

一、题目描述

Description

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

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

Input

本题有多组数据。

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

第二行 n 个数,表示每个楼房的颜色(1≤ c ≤ 1e6)。

第三行 n 个数,表示每个楼房的高度(1≤ h ≤ 1e9)。

数据保证所有组数据的 Σn ≤ 1e6 。

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

二、思路过程

        小张的故事告诉我们,暑假不要过度沉迷游戏,以致于该做的作业都被落下。

        小张的故事还警戒我们,就算自己的事情做不完,也不应该去麻烦一个陌生人,就好像我debug了一个上午,现在只想让小张退学。

        可他竟然可以让程序设计的老师无偿帮他,有黑幕啊!

        栈的基本应用。

        这道题非常基础,入栈,出栈,取栈顶元素,等等。这是一道帮助新手(我)快速入门栈的简单题目。

        我们需要让楼高入栈,确保从栈底到栈顶是递减的,栈内每一个元素就是我们在当前位置所能看到的每一栋楼房;在此基础上,统计这些楼房的颜色有几种,就是我们观察到的颜色数量。我们不关心一种颜色有多少个,但是我们关心的是有多少种颜色,非常适合采用“桶”。


三、代码实现

头文件

#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 10;

声明栈体(没什么好说的,就是书上的内容)

struct st {
	int h[1000010],c[1000010];
	int front = 0;
	void push( int height , int color ) {
		h [ front ] = height; 
		c [ front ] = color;
		front++ ;
	}
	
	void pop() {
		if ( front > 0 ) front-- ;
	}
	
	int toph() {
		if ( front > 0 ) return h [ front-1 ];
	}
	int topc() {
		if ( front > 0 ) return c [ front-1 ];
	}
	
	int size() {
		return front;
	}
};

        在这样的一个栈里,有楼房的高度height和楼房的颜色color两个信息,它们作为一个整体共同放在栈顶。

对每一组数据:

int color_num = 0; //color_num用来计数。

int n;
scanf("%d",&n); //有n栋楼
struct st stack;

for ( int i=0 ; i<n ; i++ ) {	
    scanf( "%d" , & building_c[i] ); 
    bucket_color[i+1] = 0;
//bucket_color[]指的是桶中的颜色。
//当bucket_color由0变为1时,color_num加1;当bucket_color由1变为0时,color_num减1
}

for ( int i=0 ; i<n ; i++ ) {
	int building_h;
	scanf( "%d" , & building_h );
    
    //小元素出栈
	while ( stack.size()  &&  stack.toph() <= building_h ) {
		bucket_color[ stack.topc() ] --;
		if ( bucket_color[ stack.topc() ] == 0 ) color_num--;
		stack.pop();
	}

//新元素入栈
stack.push(building_h,building_c[i]);

//当元素出入栈时,对应的颜色数也要立刻变化
bucket_color[ stack.topc() ] ++;
if ( bucket_color[ stack.topc() ] == 1 ) color_num++;

if (i!=n-1) cout << color_num << ' ';
else cout << color_num << endl;

        这里我还想补充一点:我一整个上午改来改去始终超时的原因竟然是——cin读入的速度比scanf慢!小细节决定大成败!虽然cin读入更加方便,但是当数据量庞大的时候,scanf是一个更好的选择。


四、完整代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e6 + 10;
int building_c[N],bucket_color[N]; 

struct st {
	int h[1000010],c[1000010];
	int front = 0;
	void push(int height,int color) {
		h[ front ] = height; 
		c[ front ] = color;
		front++;
	}
	
	void pop() {
		if (front > 0) front--;
	}
	
	int toph() {
		if (front > 0) return h[front-1];
	}
	int topc() {
		if (front > 0) return c[front-1];
	}
	
	int size() {
		return front;
	}
};

int main(){
	
	int m;
	scanf("%d",&m); //有m组数据
	
	
	for (int j=0;j<m;j++) {
		
		int n;
		scanf("%d",&n); //有n栋楼
		struct st stack;
		
		for (int i=0;i<n;i++) {	scanf("%d",&building_c[i]); bucket_color[i+1] = 0; }
		
		int color_num = 0;
		for (int i=0;i<n;i++) {
			int building_h;
			scanf("%d",&building_h);
			while ( stack.size()  &&  stack.toph() <= building_h ) {
				bucket_color[ stack.topc() ] --;
				if ( bucket_color[ stack.topc() ] == 0 ) color_num--;
				stack.pop();
			}
			stack.push(building_h,building_c[i]);
			bucket_color[ stack.topc() ] ++;
			if ( bucket_color[ stack.topc() ] == 1 ) color_num++;
		
		if (i!=n-1) cout << color_num << ' ';
		else cout << color_num << endl;
	}
	
}
	
	return 0;
}

        总结:这道题目不难,目的是帮助新手快速入手栈的基本操作。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值