Hrbeu 5012(二分逼近)
比较恶心的逼近 首先对2组数据排序
然后在形式上化作N*N的阵 使用DP变量保存查找深度
每次查询如果key值较小 左移一次 则排名增加(n-dp) 否则深度+1
使用二分逼近 返回ans 注意逼近时计算k的上下界
代码如下:
#include <iostream>
#include <algorithm>
using namespace std;
long A[10010];
long B[10010];
long N,K;
bool check(long key)
{
long i;
long rank=1;
long dp=0;
for (i=N-1;i>=0&&dp<=N;)
{
if (key<A[i]*B[dp])
{
rank+=(N-dp);
if (rank>K)
{
return false;
}
--i;
}
else
{
++dp;
}
}
long up=rank;
rank=1;
dp=0;
for (i=N-1;i>=0&&dp<=N;)
{
if (key<=A[i]*B[dp])
{
rank+=(N-dp);
if (rank>K)
{
return false;
}
--i;
}
else
{
++dp;
}
}
long down=rank;
return rank>=up&&rank<=down;
}
int main()
{
long T;
scanf("%ld",&T);
while (T--)
{
long i;
scanf("%ld %ld",&N,&K);
for (i=0;i<N;++i)
{
scanf("%ld",&A[i]);
}
for (i=0;i<N;++i)
{
scanf("%ld",&B[i]);
}
sort(A,A+N);
sort(B,B+N);
long low=A[0]*B[0];
long high=A[N-1]*B[N-1];
long h=low,r=high,mid,ans=h;
while(h<=r)
{
mid=(h+r)>>1;
if(!check(mid))
{
ans=mid;
h=mid+1;
}
else
{
r=mid-1;
}
}
printf("%ld\n",ans);
}
return 0;
}
#include <algorithm>
using namespace std;
long A[10010];
long B[10010];
long N,K;
bool check(long key)
{
long i;
long rank=1;
long dp=0;
for (i=N-1;i>=0&&dp<=N;)
{
if (key<A[i]*B[dp])
{
rank+=(N-dp);
if (rank>K)
{
return false;
}
--i;
}
else
{
++dp;
}
}
long up=rank;
rank=1;
dp=0;
for (i=N-1;i>=0&&dp<=N;)
{
if (key<=A[i]*B[dp])
{
rank+=(N-dp);
if (rank>K)
{
return false;
}
--i;
}
else
{
++dp;
}
}
long down=rank;
return rank>=up&&rank<=down;
}
int main()
{
long T;
scanf("%ld",&T);
while (T--)
{
long i;
scanf("%ld %ld",&N,&K);
for (i=0;i<N;++i)
{
scanf("%ld",&A[i]);
}
for (i=0;i<N;++i)
{
scanf("%ld",&B[i]);
}
sort(A,A+N);
sort(B,B+N);
long low=A[0]*B[0];
long high=A[N-1]*B[N-1];
long h=low,r=high,mid,ans=h;
while(h<=r)
{
mid=(h+r)>>1;
if(!check(mid))
{
ans=mid;
h=mid+1;
}
else
{
r=mid-1;
}
}
printf("%ld\n",ans);
}
return 0;
}