zoukankan      html  css  js  c++  java
  • A

    在这里插入图片描述
    题解一

    因为是从1-p,所以可以维护两个递增且比a[i]小的栈,如果过程中两个栈的元素数量不一样多,说明到此位置时,最小值的位置不相同。

    上面这个我没看懂原因,说的也很潦草,但是不得不让人配服的是,他还真就是对的。
    他的这个代码还可以从模拟的角度来看,尝试一下,就会发现,他的代码还真就是模拟的过程(虽然我不知道我当时怎么没有模拟对)

    #include <iostream>
    #include <stack>
    using namespace std;
    const int N = 1e5 + 10 ;
    stack<int> sta , stb ;
    int a[N] , b[N] ;
    int main()
    {
        int n ;
        while(cin >> n)
        {
          for(int i = 1 ; i <= n ;i ++) cin >> a[i] ;
          for(int i = 1 ; i <= n ;i ++) cin >> b[i] ;
            while(sta.size()) sta.pop() ;
            while(stb.size()) stb.pop() ;
            sta.push(0) , stb.push(0) ;
            int ans = 0 ;
            for(int i = 1 ;i <= n;i ++)
            {
                while(!sta.empty() && sta.top() > a[i]) sta.pop() ;
                sta.push(a[i]) ;
                while(!stb.empty() && stb.top() > b[i]) stb.pop() ;
                stb.push(b[i]) ;
                if(sta.size() == stb.size()) ans = i ;
                else break ;
            }
            cout << ans << endl ;
        }
    }
    

    另一种比较简单的做法就是
    如果第i个数之前都是处理好的,然后对于第i个数,有四种情况,增加第i个数,影响的区间是[j,i] , j 属于1 到i - 1
    分析第i个数,然后与前面的数a[j] 一一比较,如果如果数组a与数组b的比较结果不一致,也就是(a[i] > a[j] && b[i] < b[j]) || (a[i] < a[j] && b[i] > b[j])这两种情况之一,也就代表了,走向趋势不一样,直接就停止,然后可以输出答案了,也可以标志一下,a[i] 和a[j] 的关系还有两种 ,一个是 a[i] < a[j] && b[i] < b[j] ,也就是这个数比之前的a[j] 小, 那么对于区间[j , i] 影响就是最小的数变成了第i个,这个情况完全符合题意,如果a[i] > a[j] && b[i] > b[j] , 那么较小的数一定不是a[i] , 也就是第i个数完全没有价值了,比之前那个还没有用,因为之前每个区间最小的,还是第[j , i] 区间最小的,可以仔细想一想,所以这种情况可以直接break了
    我记得这个做法是当时我再网上学的一篇,它说的更详细,但是找不到了

    #include <iostream>
    using namespace std;
    int n ;
    const int N = 5e5 + 10 ;
    int a[N] , b[N] ;
    int main()
    {
        while(cin >> n)
        {
            for(int i = 1 ;i <= n;i ++) cin >> a[i] ;
            for(int i = 1 ;i <= n;i ++) cin >> b[i] ;
            bool flag = true ;
            int ans = n ;
            for(int i = 1;i <= n;i ++)
            {
                for(int j = i - 1;j ;j --)
                     if((a[i] > a[j] && b[i] < b[j]) || (a[i] < a[j] && b[i] > b[j]))
                     {
                         flag = false ;
                         break ;
                     }
                     else if(a[i] > a[j] && b[i] > b[j]) break ;
                if(!flag)
                {
                    ans = i - 1 ;
                    break ;
                }
            }
            cout << ans << endl ;
        }
        return 0 ;
    }
    

    还有一个笛卡尔树的做法,这是官方给的做法 (待续)

    每次做题提醒自己:题目到底有没有读懂,有没有分析彻底、算法够不够贪心、暴力够不够优雅。
  • 相关阅读:
    C,C++,VC++有什么区别
    RF & Microarray
    偏最小二乘法
    各种机器学习方法的优缺点
    纠错输出编码法ECOC
    遗传算法GA
    支持向量机SVM
    神经网络NN
    机器学习的基本概念
    SPI通信协议(SPI总线)学习
  • 原文地址:https://www.cnblogs.com/spnooyseed/p/12870912.html
Copyright © 2011-2022 走看看