zoukankan      html  css  js  c++  java
  • noip模拟赛 第K小数

    【问题描述】
    有两个正整数数列,元素个数分别为N和M。从两个数列中分别任取一个数
    相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少。
    【输入格式】
    输入文件名为number.in。
    输入文件包含三行。
    第一行为三个正整数N,M和K。
    第二行为N个正整数,表示第一个数列。
    第三行为M个正整数,表述第二个数列。
    【输出格式】
    输出文件名为number.out。
    输出文件包含一行,一个正整数表示第K小数。
    【输入输出样例1】

    number.in number.out
    2 3 4
    1 2
    2 1 3
    3


    【输入输出样例2】

    number.in number.out
    5 5 18
    7 2 3 5 8
    3 1 3 2 5
    16


    【数据规模与约定】

    样例点编号 N M K 元素大小(≤)
    1 20 20 150 10^4
    2 50 50 2000 10^4
    3 100 80 5000 10^9
    4 200 200 26000 10^9
    5 10000 10000 50050000 10^4
    6 1000 20000 9500000 10^4
    7 1000 20000 10000500 10^9
    8 2000 20000 190000 10^9
    9 2000 20000 199000 10^9
    10 20000 20000 210005000 10^4
    11 20000 20000 210000 10^5
    12 20000 20000 200000 10^9
    13 20000 20000 220000500 10^5
    14 20000 20000 199000500 10^9
    15 200000 200000 180000 10^4
    16 200000 200000 200000 10^9
    17 2000 200000 100001500 10^9
    18 200000 180000 19550000000 10^5
    19 200000 200000 19900010000 10^9
    20 200000 200000 20000010000 10^9


    分析:非常经典的一道题,要求第K小/大之类的显然可以二分,看比它小的数有多少个,统计个数主要还是乘法原理,将两个序列排序,然后移动两个指针,一个从小到大,一个从大到小,因为满足单调性,一个乘法就解决了.


    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    ll n, m, k, a[200010], b[200010], max1, max2, ans, cnt1, cnt2;
    
    ll check(ll x)
    {
        ll cur1 = 1, cur2 = m, sum = 0;
        while (cur2 > 0 && cur1 <= n)
        {
            while (a[cur1] * b[cur2] > x)
                cur2--;
            sum += cur2;
            cur1++;
        }
        return sum;
    }
    
    int main()
    {
        scanf("%lld%lld%lld", &n, &m, &k);
        for (ll i = 1; i <= n; i++)
        {
            scanf("%lld", &a[i]);
            max1 = max(max1, a[i]);
        }
        for (ll i = 1; i <= m; i++)
        {
            scanf("%lld", &b[i]);
            max2 = max(max2, b[i]);
        }
        sort(a + 1, a + 1 + n);
        sort(b + 1, b + 1 + m);
        ll l = 1, r = max1 * max2;
        while (l <= r)
        {
            ll mid = (l + r) >> 1;
            if (check(mid) >= k)
            {
                ans = mid;
                r = mid - 1;
            }
            else
                l = mid + 1;
        }
        printf("%lld
    ", ans);
    
        return 0;
    }
  • 相关阅读:
    oracle插入数据
    保存图片
    ASCII码排序及md5加密
    JavaScript
    HTML
    py访问Redis和zk操作
    Zookeeper集群搭建以及python操作zk
    并发编程
    Python之socket(套接字)
    Python 网络编程
  • 原文地址:https://www.cnblogs.com/zbtrs/p/7747843.html
Copyright © 2011-2022 走看看