2576: The K-th minimum number
Result | TIME Limit | MEMORY Limit | Run Times | AC Times | JUDGE |
---|---|---|---|---|---|
![]() | 5s | 32768K | 441 | 38 | Standard |
This problem is finding the K-th minimum number of a Matrix. The matrix is defined as below:
- 1. The matrix C has N rows and M columns.
- 2. C[i][j](0<=i<N,0<=j<M) is the number at the i-th row and j-th column of the Matrix.
- 3. Two arrays A and B is used to represent C. A is an array of N numbers and B is an array of M numbers. C[i][j]=A[i]*B[j] all indices start from 0.
Given the two arrays A and B, your task is to find the Kth minimum number of the Matrix C. K begins with 1.
Input
There will be several cases. Each case includes three lines.
Line 1: Three integers N, M and K.( 1<=N<=10000, 1<=M<=10000, 1<= K <=N*M )
Line 2: N integers of array A. ( -10000 <A[i] < 10000, 0<=i<N)
Line 3: M integers of array B. ( -10000 <B[i] < 10000, 0<=i<M)
The input terminates when N=M=K=0.
Output
For each test case, output the Kth minimum number in Matrix C. A single number takes up a line.
Sample Input
2 2 2 1 2 1 2 2 2 3 1 2 1 2 2 2 1 1 -2 -1 2 2 2 4 1 -2 -1 2 0 0 0
Sample Output
2 2 -4 2
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[11000],b[11000];
const int inf=(1<<31)-1;
int n,m,k;
int lessnum(int now)//严格小于
{
int cnt=0;
for(int i=0;i<n;i++)//逐行找小于now的数字的个数
{
if(a[i]>0)//c[i]行从左往右是递增
{
if(a[i]*b[0]>=now) continue;//如果c[i]行最小的仍大于now,则这一行不必再找
int l=0,r=m;
while(l<r)//二分查找c[i]行小于now的数字的个数
{
int mid=(l+r)>>1;
if(a[i]*b[mid]<now) l=mid+1;//c[i][j]=a[i]*b[j]
else r=mid;
}//查找结束后l表示第一个大于now的数字的位置
cnt+=l;//因为数组下标是从0开始,所以第一个大于now的数字的位置也是小于now的数字的个数
}
else if(a[i]<0)//c[i]行是递减的
{
if(a[i]*b[m-1]>=now) continue;//如果c[i]行最小的仍大于now,则这一行不必再找
int l=0,r=m;
while(l<r)//二分查找c[i]行大于等于now的数字的个数
{
int mid=(l+r)>>1;
if(a[i]*b[mid]>=now) l=mid+1;
else r=mid;
}
cnt+=m-l;//m-l表示小于now的数字的个数
}
else if(now>0) cnt+=m;
}
return cnt;
}
void find(int &maxn,int &minc)//找出最大值和最小值,因为数据有可能是负数,所以要考虑四种情况
{
//找最大值
if(a[0]*b[0]>maxn) maxn=a[0]*b[0];
if(a[n-1]*b[0]>maxn) maxn=a[n-1]*b[0];
if(a[0]*b[m-1]>maxn) maxn=a[0]*b[m-1];
if(a[n-1]*b[m-1]>maxn) maxn=a[n-1]*b[m-1];
//找最小值
if(a[0]*b[0]<minc) minc=a[0]*b[0];
if(a[n-1]*b[0]<minc) minc=a[n-1]*b[0];
if(a[0]*b[m-1]<minc) minc=a[0]*b[m-1];
if(a[n-1]*b[m-1]<minc) minc=a[n-1]*b[m-1];
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)==3,n||m||k)
{
for(int i=0;i<n;i++) scanf("%d",&a[i]);
for(int i=0;i<m;i++) scanf("%d",&b[i]);
sort(a,a+n);sort(b,b+m);//从小到大排序
int maxn=-inf,minc=inf;//初始化最大、小值
find(maxn,minc);//找最大、小值
while(minc<maxn)//二分查找第k小数
{
int mid=(maxn+minc+1)>>1;//+1 important
if(lessnum(mid)<k) minc=mid;
else maxn=mid-1;//-1 important
}
printf("%d/n",minc);
}
return 0;
}