NCST--HBCPC2021选拔赛题解E
Envelope
来源:http://acm.ncst.edu.cn/problem.php?cid=1001&pid=4
标签:【思维】【二分答案】【矩阵运算】
题目简述
新年到了,夏教授正在分发新年红包,但是像他这样的隐喻狂热爱好者却为他的学生们造成了困扰。 他向所有人保证,能解决这个问题的人都会得到一个巨大的美味蛋糕。难题是:给定一个行向量𝐴和列向量𝐵。 你能找到𝐵∗𝐴的中位数吗?
Input
两行,分别表示向量𝐴,B。每行包含𝑛个整数,并保证0≤𝑛≤105,0≤𝑛i≤103,且𝑛为奇数。
Output
输出矩阵B*A的中位数计算在单独一行。
Sample Input
1 2 3
4 5 6
Sample Output
10
More Info
The cake is a lie.
题目思路
对A[]和B[]进行升序排序,因为Ai<= A i+1,Bi <= Bi+1,所以相乘后得到的矩阵必有Cii <= Ci+1,i+1, 对于每行和每列也必升序排列。但是副对角线的顺序不确定。
借用一下别人的题解:
代码(附注释)
#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
#define endl '\n'
#define int long long
vector<int>A,B;
int n;
int check(int x)
{
int res=0,i=n-1,j=0;
while(i>=0 && j<n){
if(B[i]*A[j]<=x){
res+=i+1;
++j;
}
else --i;
}
return res;
}
signed main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int x;
while(1){//输入卡了半天-_-|||
cin>>x;
if(cin.get()!=' ') break;
A.push_back(x);
}
while(1){
cin>>x;
if(cin.get()!=' ') break;
B.push_back(x);
}
//cout<<A.size()<<' '<<B.size()<<endl;
sort(A.begin(),A.end());//排序
sort(B.begin(),B.end());
n=A.size();
//二分答案
int l=A[0]*B[0],r=A[n-1]*B[n-1];
while(l<r){
int mid=l+r>>1;
if(check(mid)>n*n/2) r=mid;
else l=mid+1;
}
cout<<l<<endl;
return 0;
}