• 51nod 1105:第K大的数


    基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题
     收藏
     关注
    数组A和数组B,里面都有n个整数。数组C共有n^2个整数,分别是A[0] * B[0],A[0] * B[1] ......A[1] * B[0],A[1] * B[1]......A[n - 1] * B[n - 1](数组A同数组B的组合)。求数组C中第K大的数。
    例如:A:1 2 3,B:2 3 4。A与B组合成的C包括2 3 4 4 6 8 6 9 12共9个数。
    Input
    第1行:2个数N和K,中间用空格分隔。N为数组的长度,K对应第K大的数。(2 <= N <= 50000,1 <= K <= 10^9)
    第2 - N + 1行:每行2个数,分别是A[i]和B[i]。(1 <= A[i],B[i] <= 10^9)
    Output
    输出第K大的数。
    Input示例
    3 2
    1 2
    2 3
    3 4
    Output示例
    9

    之前做过的left right都是数组的下标,找数组中的元素。这次是直接给那个数的范围,找数组中的数。

    双二分。一开始我是想第k大的数,即是 第n*n-k+1小的数,所以找小的元素,结果前19组test都过了,就第20组一直WA。后来想N最大50000,N*N超过了long long了。这个思路只能被划掉。乖乖找第k大的,记录有多少比mid大的,再去比较。

    代码:

    <pre name="code" class="cpp">#include <iostream>
    #include <algorithm>
    #include <cmath>
    #include <vector>
    #include <string>
    #include <cstring>
    #pragma warning(disable:4996)
    using namespace std;
    
    long long a[50005], b[50005];
    int len, k;
    
    int search(long long y, long long x)
    {
    	int i, left = 1, right = len;
    	long long mid, ans=len;
    	while (left <= right)
    	{
    		mid = left + (right - left) / 2;
    		if (a[y] * b[mid] >= x)
    		{
    			ans = min(ans, mid);
    			right = mid - 1;
    		}
    		else
    		{
    			left = mid + 1;
    		}
    	}
    	return ans;
    }
    
    bool check(long long x)
    {
    	int i, ans = 0;
    	for (i = 1; i <= len; i++)
    	{
    		if (a[i] * b[len] < x)continue;
    		ans += ((len- search(i, x))+1);
    	}
    	return ans >= k;
    }
    
    int main()
    {
    	int i;
    	long long start, end, mid, ans;
    	cin >> len >> k;
    	for (i = 1; i <= len; i++)
    		cin >> a[i] >> b[i];
    	
    	sort(a + 1, a + len + 1);
    	sort(b + 1, b + len + 1);
    
    	start = a[1] * b[1] - 1;
    	end = a[len] * b[len] + 1;
    	ans = 0;
    
    	while (end - start > 1)
    	{
    		mid = start + (end - start) / 2;
    		if (check(mid))
    		{
    			ans = max(ans, mid);
    			start = mid;
    		}
    		else
    		{
    			end = mid;
    		}
    	}
    	cout << ans << endl;
    
    	return 0;
    }


    
        
            

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    linux日常。
    tp5中的config类和config助手函数
    TP5隐藏index.php
    TP5读取数据概述
    TP5的安装部署概要
    eclipse4.7中文包安装方法。
    利用mysqldump备份magento数据库
    MySQL 基础知识
    PHP 基础知识
    妖怪与和尚过河问题
  • 原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4899583.html
Copyright © 2020-2023  润新知