[USACO 2009 Mar S]Look Up_via牛客网

题目

链接:https://ac.nowcoder.com/acm/contest/28537/N
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld

题目描述

Farmer John’s N (1 <= N <= 100,000) cows, conveniently numbered 1…N, are once again standing in a row. Cow i has height Hi (1 <= Hi <= 1,000,000).
Each cow is looking to her left toward those with higher index numbers. We say that cow i ‘looks up’ to cow j if i < j and Hi < Hj. For each cow i, FJ would like to know the index of the first cow in line looked up to by cow i.
Note: about 50% of the test data will have N <= 1,000.

输入描述:

* Line 1: A single integer: N
* Lines 2..N+1: Line i+1 contains the single integer: Hi

输出描述:

* Lines 1..N: Line i contains a single integer representing the smallest index of a cow up to which cow i looks. If no such cow exists, print 0.

示例1

输入

6 
3 
2 
6 
1 
1 
2 

输出

3
3
0
6
6
0

说明

FJ has six cows of heights 3, 2, 6, 1, 1, and 2.
Cows 1 and 2 both look up to cow 3; cows 4 and 5 both look up to cow 6; and cows 3 and 6 do not look up to any cow.

题解

这道题目可以使用单调栈,

使用方法一:

方法类似于学姐讲的滑动窗口

我认为方法为:适时丢弃,

本来暴力就是n^2,但是由于适时地删除,所以时间复杂度立马就降到了n

丢弃内容: 遇到一个高度的奶牛,看我的栈里面的内容,从小往大比较,如果大于栈中的奶牛,那么就删除栈顶的,继续比,

一直比较
比栈中所有的都大
那么栈中的所有奶牛没有机会
原因:一.比他靠前,二.比它大
发现栈中的一个比他大
也保留着
万一有奶牛比他小,那么就是他

使用方法二:

由于这道题目面需要知道某个奶牛仰慕的牛的序号,所以在栈里面不能仅仅存放牛的高度

以及

[NOIP2016]蚯蚓

这里面的问题,我经过归纳,有三种解决办法

  1. 制造一个结构体或者是pair对,直接存之
  2. 找依赖关系(可以拿一个经过题设条件推倒得到另一个),只记录一个源(就像是这道题目里面的,我可以只记录位置,通过奶牛高度数组来进行推倒)
  3. 全部经过特殊化,使得其具有一定的初始值,成为一种经过一个公式就可以推倒的内容(eg.[NOIP2016]蚯蚓)

代码

#include <iostream>
#include <stack>
using namespace std;
#define MAX 100007
int s[MAX];
int ans[MAX];
stack<int>st;
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n;
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> s[i];
	for (int i = n; i >= 1; i--)
	{
		while (!st.empty() && s[i] >= s[st.top()])
			st.pop();
		if (!st.empty())
		{
			ans[i] = st.top();
			st.push(i);
		}
		else
		{
			ans[i] = 0;
			st.push(i);
		}
	}
	for (int i = 1; i <= n; i++)
	{
		cout << ans[i] << endl;
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值