zoukankan      html  css  js  c++  java
  • 洛谷 P2947 [USACO09MAR]向右看齐Look Up【单调栈】

    题目描述
    Farmer John's N (1 <= N <= 100,000) cows, conveniently numbered 1..N, are once again standing in a row. Cow i has height H_i (1 <= H_i <= 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 H_i < H_j. 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.

    约翰的N(1≤N≤10^5)头奶牛站成一排,奶牛i的身高是Hi(l≤Hi≤1,000,000).现在,每只奶牛都在向右看齐.对于奶牛i,如果奶牛j满足i<j且Hi<Hj,我们可以说奶牛i可以仰望奶牛j. 求出每只奶牛离她最近的仰望对象.

    Input

    输入输出格式
    输入格式:

    • Line 1: A single integer: N

    • Lines 2..N+1: Line i+1 contains the single integer: H_i

    第 1 行输入 N,之后每行输入一个身高 H_i。

    输出格式:

    • 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.

    共 N 行,按顺序每行输出一只奶牛的最近仰望对象,如果没有仰望对象,输出 0。

    输入输出样例
    输入样例#1:
    6
    3
    2
    6
    1
    1
    2
    输出样例#1:
    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.

    【输入说明】6 头奶牛的身高分别为 3, 2, 6, 1, 1, 2.

    【输出说明】奶牛#1,#2 仰望奶牛#3,奶牛#4,#5 仰望奶牛#6,奶牛#3 和#6 没有仰望对象。

    【数据规模】

    对于 20%的数据: 1≤N≤10;

    对于 50%的数据: 1≤N≤1,000;

    对于 100%的数据:1≤N≤100,000;1≤H_i≤1,000,000;
    【分析】:
    首先能不能随便一点,我就是维护一个栈的单调递增(不管三七二十一),那么我要如何利用呢?

    ① 3进栈;

    ② 2比栈顶元素小,不要;

    ③ 6比栈顶元素大,进去;

    ④ 。。。。。等等窝们不是要求一个元素比他的最近么?这样子2都不要了。。然后6过来了还进栈。。这不是背道而驰了。

    所以方案错误;

    那么不是维护单调递增,就是维护一下单调递减呗;

    ① 3进栈

    ② 2比3小进栈

    ③ 6比2大,咦?一下就是6比2大,而且后面都没有碰到,所以6一定是2的单侧最近,然后2出栈,并且2的答案就是6元素的位置。然后看3,3还是比6小,OK,满足。最后把6进栈。

    ④ 1进栈

    ⑤ 1进栈

    ⑥ 2的时候,栈里面的两个1出栈,然后2进栈

    ⑦ 最后注意,栈里面还有6和2这两个元素,可惜没有他们的答案,那就是0;
    【代码】:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <sstream>
    #include <queue>
    #include <typeinfo>
    #include <fstream>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    #define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
    #define test freopen("test.txt","r",stdin)
    #define maxn 1000005
    #define mod 10007
    #define eps 1e-5
    const int inf=0x3f3f3f3f;
    const ll infll = 0x3f3f3f3f3f3f3f3fLL;
    inline ll read()
    {
        ll x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int n;
    struct node
    {
        int num,pos;
    }tmp;
    stack<node> st;
    int ans[maxn];
    int a[maxn];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        tmp.num=a[1];
        tmp.pos=1;
        st.push(tmp);
        for(int i=2;i<=n;i++)
        {
            while(!st.empty() && a[i]>st.top().num){
                ans[st.top().pos]=i;
                st.pop();
            }
            tmp.num=a[i];
            tmp.pos=i;
            st.push(tmp);
        }
        while(!st.empty())
        {
            ans[st.top().pos]=0;
            st.pop();
        }
        for(int i=1;i<=n;i++)
        {
            printf("%d
    ",ans[i]);
        }
    }
    
    

    【手写栈】

    #include<bits/stdc++.h>
    using namespace std;
    int f[1501],f2[1501][1501],b[100001],top=1,n,x,m;
    struct aaa {int num,data;}a[100001],filo[100001];//用结构体来实现,num为序号,data为身高
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
        cin>>a[i].data;
        a[i].num=i;      //边读边做
        for(int j=top;j>=1;j--)
        if(filo[top].data<a[i].data)b[filo[top].num]=a[i].num,top--;//判断,记录,出栈
        filo[++top]=a[i];//压栈
        }
        for(int i=1;i<=n;i++)cout<<b[i]<<endl;//输出!
        return 0;//华丽丽的结束!
    }
    
  • 相关阅读:
    java中Collection 与Collections的区别
    Bridge桥接模式(设计模式11)
    动态代理模式(设计模式10)
    代理模式(静态代理)(设计模式9)
    适配器模式(工厂模式8)
    原型模式(工厂模式7)
    建造者模式(工厂模式6)
    抽象工厂模式(工厂模式5)
    工厂模式(工厂模式4)
    简单工厂模式(工厂模式3)
  • 原文地址:https://www.cnblogs.com/Roni-i/p/9382477.html
Copyright © 2011-2022 走看看