zoukankan      html  css  js  c++  java
  • 1105 第K大的数

    基准时间限制:1 秒 空间限制:131072 KB 
    数组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
    思路:二分,先排序,首先二分答案,答案的范围在ans[0]*bns[0]---ans[n-1]*bns[n-1]之间,然后二分统计这个答案的前面是否有大于等于k个比他大的,符合的话并且二分检查这个答案是否存在。
     1 #include<stdio.h>
     2 #include<algorithm>
     3 #include<iostream>
     4 #include<string.h>
     5 #include<queue>
     6 #include<math.h>
     7 #include<set>
     8 #include<vector>
     9 #include<string.h>
    10 using namespace std;
    11 typedef long long LL;
    12 typedef struct node {
    13     LL x;
    14     LL y;
    15 } ss;
    16 LL ans[60000];
    17 LL bns[60000];
    18 bool check(LL n,LL N,LL M) {
    19     int i,j;
    20     LL cnt = 0;
    21     for(i = 0; i < N; i++) {
    22         int l = 0;
    23         int r =N;
    24         int id = -1;
    25         while(l<=r) {
    26             int mid = (l+r)/2;
    27             if(bns[mid]*ans[i]>=n) {
    28                 id = mid;
    29                 r = mid - 1;
    30             } else l= mid + 1;
    31         }
    32         if(id!=-1) {
    33             if(n==12)printf("%d
    ",id);
    34             cnt += N-id;
    35         }
    36     }
    37     if(cnt>=M)return true;
    38     return false ;
    39 }
    40 bool er(int n,int m,int ask);
    41 bool  test(LL mid,LL N,LL M);
    42 int main(void) {
    43     LL N,M;
    44     scanf("%lld %lld",&N,&M);
    45     int i,j;
    46     for(i = 0; i < N; i++) {
    47         scanf("%lld %lld",&ans[i],&bns[i]);
    48     }
    49     sort(ans,ans+N);
    50     sort(bns,bns+N);
    51     LL ak = ans[0]*bns[0];
    52     LL bk = ans[N-1]*bns[N-1];
    53     LL all = -1;//printf("%lld %lld
    ",ak,bk);
    54     while(ak<=bk) {
    55         LL mid = (ak+bk)/2;
    56         if(check(mid,N,M)) {
    57             if(test(mid,N,M))
    58                 all = max(mid,all);
    59             ak = mid + 1;
    60         } else bk = mid-1;
    61     }
    62     printf("%lld
    ",all);
    63     return 0;
    64 }
    65 bool  test(LL mid,LL N,LL M) {
    66     int i,j;
    67     LL kk;
    68     for(i = 0; i < N; i++) {
    69         if(mid%ans[i]==0) {
    70             if(er(0,N,mid/ans[i]))
    71                 return true;
    72         }
    73     }
    74 }
    75 bool er(int n,int m,int ask) {
    76     if(n>m)return false;
    77     int mid = (n+m)/2;
    78     if(bns[mid]==ask) {
    79         return true;
    80     } else if(bns[mid]>ask) {
    81         return er(n,mid-1,ask);
    82     } else return er(mid+1,m,ask);
    83 }

    复杂度N*log(N);

    
    
    油!油!you@
  • 相关阅读:
    SQLAlchemy Table(表)类方式
    MySQL简单入门
    第四次作业
    第三次随笔
    第二次随笔
    第一次随笔
    第四次随笔
    第三次作业
    第二次随笔
    第一次随笔
  • 原文地址:https://www.cnblogs.com/zzuli2sjy/p/5824453.html
Copyright © 2011-2022 走看看