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, 对于每行和每列也必升序排列。但是副对角线的顺序不确定。
借用一下别人的题解:
image

代码(附注释)

#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;
}
posted @ 2021-05-24 09:42  unravel_CAT  阅读(135)  评论(0编辑  收藏  举报