• Preparing for Merge Sort(二分)


    Preparing for Merge Sort

    思路

    手动模拟样例一后惊奇的发现了一个规律

    这组样例一共有两个队列输出,我们发现任意时刻每组数据都满足一个条件,最末尾的数字是严格按照单调递减的顺序的。我们每一次添加数字的操作,都是从下向上寻找最后一个小于当前要添加数字的队列编号。

    这一操作是不是很像(lower\_bound - 1)的操作,但是却是一个反向的(lower\_bound - 1),于是我又开了一个数组来反向存最后一个数字,假如原本的第一组数据的最后一个数字是1,我们在下标为((n - 1))的数组上存储1,这样就可以实现我们的二分查找位置操作了。

    再来说一下二分查找的细节。

    假如我们的(lower\_bound)返回的是(n)下标,这说明我们没有找到比当前数字更大的数字,所以这里我们需要特判,将其添加到第一组队列数据当中去。

    如果我们的(lower_bound)返回的是下标(n - 1)说明队列1末尾的最后一个数字比当前要添加的数字是更大的,所以我们需要添加到队列2当中去。

    还有一点就是这里好像一定得用动态数组存答案,不然(2e5 * 2e5)会爆内存。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int N = 2e5 + 10;
    
    vector<int> ans[N];
    int a[N], n, m, b[N];
    
    int main() {
        // freopen("in.txt", "r", stdin);
        int t;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%d", &t);
            int pos = lower_bound(b, b + n, t) - b;
            if(pos == n) {
                b[n - 1] = t;
                a[0] = t;
                ans[0].push_back(t);
            }
            else {
                b[pos - 1] = t;
                a[n - pos] = t;
                ans[n - pos].push_back(t);
            }
        }
        for(int i = 0; a[i]; i++) {
            for(int j = 0; j < ans[i].size(); j++)
                printf("%d ", ans[i][j]);
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    经典机器学习算法总结
    从0开始学Python---01
    Android-Canvas.save() Canvas.restore() 总结
    Android-属性动画原理总结
    设计模式-外观模式
    设计模式-模板方法
    设计模式-装饰者模式
    设计模式-策略模式
    设计模式-工厂方法模式
    设计模式-简单工厂模式
  • 原文地址:https://www.cnblogs.com/lifehappiness/p/12831801.html
Copyright © 2020-2023  润新知