蓝桥杯省赛无忧 编程12 四元组问题

蓝桥杯省赛无忧 编程12 四元组问题_第1张图片
蓝桥杯省赛无忧 编程12 四元组问题_第2张图片
蓝桥杯省赛无忧 编程12 四元组问题_第3张图片

#include 
using namespace std;
bool FoursNumberFind(vector<int>& nums) {
    stack<int> st;
    int n = nums.size(), k = INT_MIN, INF = INT_MAX;
    //min_r[i] = min(nums[r]), i < r < n。
    //表示第i个数(不包括第i个数)右边的最小值
    vector<int> min_r(n, INF);
    // 用前缀和方法求 min_r 数组
    for (int i = n - 2; i >= 0; --i) {
        min_r[i] = min(min_r[i + 1], nums[i + 1]);
    }
    //用单调栈求下标位 nums[c] < nums[a] < nums[b] 的情况
    for(int i = 0; i < n; ++i){
        // 下标 i 即为 c ,k 即为 nums[a]
        if(nums[i] < k)  { //如果存在  nums[c] < nums[a] < nums[b] 的情况
            //判断 c 的右边是否 有比 nums[c] 小的数, 有则表示存在下标 d ,返回true
            if(nums[i] > min_r[i]) return true;
        }
        // 如果栈不为空并且栈顶元素小于当前访问的元素
        while(!st.empty() && st.top() < nums[i]) {
            //需要找满足小于nums[b]的最大 k 值
            k = max(k,st.top());
            st.pop();
        }
        //压入栈顶,即为更新 nums[b]
        st.push(nums[i]);
    }
    return false;
}
int main() {
    int n;
    cin >> n;
    vector<int> nums(n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &nums[i]);
    }
    if (FoursNumberFind(nums)) {
        cout << "YES" << endl;
    } else {
        cout << "NO" << endl;
    }
    return 0;
}

代码实现了检测一个数组中是否存在特定的索引模式,即 a < b < c < dnums[d] < nums[c] < nums[a] < nums[b]
代码分析:

  1. 函数 FoursNumberFind 接收一个整数数组 nums 作为参数,并试图找出是否存在上述模式。如果找到,函数返回 true,否则返回 false

  2. 首先,定义一个栈 st 来帮助我们跟踪可能的 nums[c] 值,并将整数 k 初始化为 INT_MIN 来表示我们尚未找到一个有效的 nums[a]。同时,创建一个向量 min_r,用于存放从当前位置起右侧的最小值。

  3. 接着,使用一个前向遍历循环来填充 min_r 数组,记录数组中每个元素右边的最小值。

  4. 再使用一个循环从左到右遍历 nums

    • 判断当前元素是否小于 k,即判断是否 nums[c] < nums[a]。如果是,并且当前元素也大于它右侧的最小值,这意味着存在一个 nums[d],因此返回 true

    • 使用一个while循环和栈来维护和更新可能的 nums[b] 值。如果栈非空并且栈顶的值小于当前元素,那么说明找到了一个新的 nums[b](当前元素),于是更新 k(作为 nums[a])为栈顶的值,并从栈中弹出这个栈顶元素。

    • 将当前元素压入栈中,代表一个新的候选的 nums[b]

  5. 如果上述循环结束后没有找到满足条件的下标组合,函数返回 false

  6. main 函数中,程序读取用户输入的数组长度 n 和数组元素,然后调用 FoursNumberFind 函数来确定是否存在所描述的模式。根据函数返回的布尔值,程序输出 YESNO

代码使用了一个单调栈来优化搜索过程,并避免了暴力枚举的 O(n^4) 复杂度,使得算法的性能得到了显著的提升。标准输入和输出流(cincout)用于接收输入和输出结果,提供了与用户交互的接口。

你可能感兴趣的:(蓝桥杯省赛无忧,蓝桥杯,算法,c++)