zoukankan      html  css  js  c++  java
  • 题解【CJOJ2608】[JZOJ 100043]第k小数

    Description

    有两个非负整数数列,元素个数分别为N和M。从两个数列中分别任取一个数相乘,这样一共可以得到N*M个数,询问这N*M个数中第K小数是多少。

    时间限制为20ms

    Input

    输入文件包含三行。
    第一行为三个正整数N,M和K。
    第二行为N个整数,表示第一个数列。
    第三行为M个整数,表述第二个数列。

    Output

    输出文件包含一行,一个正整数表示第K小数。

    Sample Input

    Sample1:
    2 3 4
    1 2
    2 1 3

    Sample2:
    5 5 18
    7 2 3 5 8
    3 1 3 2 5

    Sample Output

    Sample1:
    3

    Sample2:
    16

    Hint

    Pic

    Source

    二分 /单调性
    source JZOJ 100043
    鸣谢陈思宇制作数据!

    Solution

    我们先对于a、b数组分别排一次序,使这两个数组都具有单调性。

    考虑二分答案。

    假设现在二分到了mid,那么前k小的数都应满足a[i]*b[j]≤mid。

    现在,我们要枚举i和j使得mid满足上述条件。

    考虑如何快速地算出j。

    由于a、b数组都具有了单调性,因此我们得到的j也是单调递减的,就可以利用单调性轻松求出j。

    所以我们得出的算法的时间复杂度为O(N*log(最大的数)),轻松通过!

    Code

     1 #include <bits/stdc++.h>
     2 #define int long long
     3 
     4 using namespace std;
     5 
     6 inline int read()//快读
     7 {
     8     int f = 1, x = 0;
     9     char c = getchar();
    10 
    11     while (c < '0' || c > '9')
    12     {
    13         if (c == '-')
    14             f = -1;
    15         c = getchar();
    16     }
    17 
    18     while (c >= '0' && c <= '9')
    19     {
    20         x = x * 10 + c - '0';
    21         c = getchar();
    22     }
    23 
    24     return f * x;
    25 }
    26 
    27 int n, m, k, a[20005], b[20005];
    28 
    29 signed main()
    30 {
    31     n = read(), m = read(), k = read();
    32 
    33     for (register int i = 1; i <= n; i++)
    34     {
    35         a[i] = read();
    36     }
    37 
    38     for (register int i = 1; i <= m; i++)
    39     {
    40         b[i] = read();
    41     }
    42 
    43     sort(a + 1, a + 1 + n);//排序
    44     sort(b + 1, b + 1 + m);
    45 
    46     int l = 1, r = a[n] * b[m];
    47 
    48     while (l < r)//二分
    49     {
    50         int mid = (l + r) >> 1, sum = 0;
    51 
    52         for (register int i = 1, j = m; i <= n; i++, sum = sum + j)//枚举i,并且计算满足条件的个数
    53         {
    54             while (a[i] * b[j] > mid)//如果满足条件
    55             {
    56                 --j;//每次更新j
    57             }
    58         }
    59 
    60         if (sum >= k)//如果答案比k大
    61         {
    62             r = mid;//缩小最大值范围
    63         }
    64         else
    65         {
    66             l = mid + 1;//否则更新最小值
    67         }
    68     }
    69 
    70     printf("%lld", l);//输出符合条件的答案个数
    71 
    72     return 0;//结束
    73 }
  • 相关阅读:
    无线鼠标换电池了
    Jython Interactive Servlet Console YOU WILL NEVER KNOW IT EXECLLENT!!! GOOD
    Accessing Jython from Java Without Using jythonc
    jython podcast cool isnt't it?
    Python里pycurl使用记录
    Creating an Interactive JRuby Console for the Eclipse Environment
    微软为AJAX和jQuery类库提供CDN服务
    Download A File Using Cygwin and cURL
    What is JMRI?这个是做什么用的,我真没看懂但看着又很强大
    用curl 发送指定的大cookie的http/https request
  • 原文地址:https://www.cnblogs.com/xsl19/p/10520045.html
Copyright © 2011-2022 走看看