1 条题解

  • 0
    @ 2022-10-9 10:05:04

    本题的数据范围导致主要时间消耗会在输入输出中,加上输入输出优化后,才能看出下面两个程序的差距。

    std::sort、O(NlogN)O(N\log N)

    #include <bits/stdc++.h>
    using namespace std;
    int n, k;
    int a[1123456];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n >> k;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        k = n - k + 1; //第 k 大 -> 第 new_k 小
        sort(a + 1, a + n + 1);
        cout << a[k] << "\n";
        return 0;
    }
    

    快排思想求第 k 大数,O(N)O(N)

    #include<bits/stdc++.h>
    using namespace std;
    int n, k;
    int a[1000000+5]; 
    //对 a[l]~a[r] 进行快速排序 ,只需要保证 a[k] 是正确的 
    void quick_sort(int l,int r,int k){
    	//边界条件 
    	if(l>=r) //只有一个元素或者区间不合法 
    		return; 
        //可选操作:更换基准数(下面演示的是换成中间的数作为基准)
    	int mid = (l+r)/2;
    	swap(a[l],a[mid]);
    	//挑一个基准数
    	int key = a[l];
    	//划分左右:左边小于等于key,右边大于等于key
    	int pl = l, pr = r;
    	while(pl<pr)//还没有都指到空穴 
    	{	
    		// ( ) x x x x x
    		//  pl         pr
    		// 找到右边下一个比 key 小的,放在 pl 的位置
    		while(pr>pl&&a[pr]>=key)
    			pr--;
    		a[pl]=a[pr];
    		//  x x x ( ) x x
    		//  pl     pr
    		// 找到左边下一个比 key 大的,放在 pr 的位置
    		while(pl<pr&&a[pl]<=key)
    			pl++;
    		a[pr]=a[pl];
    	}
    	//(划分好后:a[l~pl-1]<=a[pl/pr]<=a[pr+1~r]) 
    	//  x x x (   ) x x
    	//        pl/pr
    	a[pl] = key;
    	//分别对左右进行快速排序
    	if(l<=k && k<=pl-1) 
    		quick_sort(l,pl-1,k);
    	else if(pr+1<=k && k<=r)
    		quick_sort(pr+1,r,k);
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cin >> n >> k;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
        k = n - k + 1; //第 k 大 -> 第 new_k 小
        quick_sort(1, n, k); //对 a[1]~a[n] 进行排序,只需要保证 a[k] 正确即可 
        cout << a[k] << "\n";
        return 0;
    }
    
    
    • 1

    信息

    ID
    1086
    时间
    1000ms
    内存
    256MiB
    难度
    5
    标签
    递交数
    78
    已通过
    32
    上传者