问题 H: 商店繁荣度

题目描述

在一条繁华的街道上有N个商店,每个商店都有一个繁华度a_i。LZY现在想知道,每个商店的右边有没有其它商店繁华度比当前商店低的。
对于每个商店,找到它右边最远位置pos,满足a_pos < a_i,输出 pos - i - 1,若右边没有比当前商店繁华度低的,则输出-1

输入

测试样例由多组测试数据组成。
每组样例第一行输入一个数组的大小n ( 2 <= n <= 1e5 ),第二行输入n个元素ai ( 1 <= ai <= 1e9 )

输出

每组样例输出一行答案,

样例输入

6
10 8 5 3 50 45
5
10 3 1 10 11

样例输出

2 1 0 -1 0 -1
1 0 -1 -1 -1

silu

逆推,如果有比当前数小的,就更新最小值,顺便保存在数组里
只要min被更新,就说明右边没有比他小的,直接-1;
如果比当前数大,说明右边有比它小的,用二分查找数组里最小的数,然后按题目要求操作

daima

#include<bits/stdc++.h>
using namespace std;
int ans[100005];
int numS[100005];
int flag[100005];
int a[100005];
int main()
{
	ios::sync_with_stdio(false);
	int n,j;
	while(cin>>n){
		memset(ans,0,sizeof(ans));		//初始化 
		memset(numS,0,sizeof(numS));
		memset(flag,0,sizeof(flag));
		memset(a,0,sizeof(a));
		j=0;int minN=999999999;
		for(int i=0;i<n;i++){
			cin>>a[i];					//输入 
		}
		for(int i=n-1;i>=0;i--){		//逆序遍历 
			if(a[i]<=minN){				//如果小于当前最小值 
				numS[j]=a[i];			//保存这个数 
				flag[j]=i;				//和它的位置 
				j++;					//下一个 
				minN=a[i];				//更新最小值 
				ans[i]=-1;				
			}else{
				int pos;				//如果不小于当前最小值 
				int top=0;				//说明右边有更小的 
				int end=j;				//可以准备二分查找 
				while(top<=end){		
					int mid=(top+end)/2;//在刚刚保存的那个数组里找最小的 
					if(a[i]>numS[mid]){	 
						end=mid-1;		//想左 
						pos=flag[mid];	//保存在pos里 
					}else{
						top=mid+1;		//向右 
					}
				}
				ans[i]=pos-i-1;
			}
		}
		for(int i=0;i<n;i++){			//输出 
			if(i!=0)cout<<' ';
			cout<<ans[i];
		}
		cout<<endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值