A--Thanks, TuSimple!
思路:
题目要求男女搭配,实际上只有1-0搭配,就只有两种情况了
(1)男1,女0,且H(男)<H(女);
(2)男0,女1,且H(男)>H(女);
所以找到合适的男女就好了,可以对称的考虑男女两种情况,以男1,女0为例,
将所有较矮的的男士放入树状数组中,然后给女生找,如果找到了合适的男生就更新一下树状数组,就表示删除了那个男生,然后统计次数+1,否则跳过即可。
同理,将所有较矮的女生放入树状数组中,让男生找,如果找到了合适的女生就更新一下树状数组,就表示删除了那个女生,然后,统计次数+1,否则跳过即可。
所有统计的次数就是最终的答案。
但是由于男生女生的身高过大,数组肯定装不下,所以提前离散化处理一下就好了(感谢队友提醒)。
扫描二维码关注公众号,回复:
5947017 查看本文章
------------------------------------------------------------------------------------------------------------------------分割线--------------------------------------其实贪心也可以了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<unordered_map>
#include<set>
using namespace std;
const int maxn = 500300;
struct Node{
int fg,hi;
};
Node boy[maxn],girl[maxn];
int tree[maxn],vis[maxn];
bool cmp(Node a,Node b){
return a.hi<b.hi;
}
int lowbit(int x){
return x&(-x);
}
void update(int x,int y){
for(int i=x;i<maxn;i+=lowbit(i)) tree[i]+=y;
}
int sum(int x){
int sum = 0;
for(int i=x;i>1;i-=lowbit(i)){
sum+=tree[i];
if(sum>=1) return sum;
}
return sum;
}
set <int> st;
unordered_map <int,int> mp;
int main(void){
int T,i,j,n,m;
//printf("%d\n",1<<31-1);
scanf("%d",&T);
while(T--){
memset(vis,0,sizeof(vis));
st.clear();mp.clear();
int cnt = 0;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%d",&boy[i].hi);
if(!st.count(boy[i].hi)){
st.insert(boy[i].hi);
vis[cnt++] = boy[i].hi;
}
}
for(i=1;i<=m;i++){
scanf("%d",&girl[i].hi);
if(!st.count(girl[i].hi)){
st.insert(girl[i].hi);
vis[cnt++] = girl[i].hi;
}
}
for(i=1;i<=n;i++) scanf("%d",&boy[i].fg);
for(i=1;i<=m;i++) scanf("%d",&girl[i].fg);
sort(vis,vis+cnt);
for(i=0;i<cnt;i++){
mp[vis[i]] = i+1;
}
for(i=1;i<=n;i++) boy[i].hi = mp[boy[i].hi];
for(i=1;i<=m;i++) girl[i].hi = mp[girl[i].hi];
int ans = 0;
//1b->0g;
sort(girl+1,girl+1+m,cmp);
memset(tree,0,sizeof(tree));
for(i=1;i<=n;i++){
if(boy[i].fg==1) update(boy[i].hi,1);
}
for(i=1;i<=m;i++)
if(girl[i].fg==0){
if(sum(girl[i].hi)>0){
ans++;
update(girl[i].hi,-1);
}
}
//1g->0b;
memset(tree,0,sizeof(tree));
sort(boy+1,boy+1+n,cmp);
for(i=1;i<=m;i++)
if(girl[i].fg==1) update(girl[i].hi,1);
for(i=1;i<=n;i++)
if(boy[i].fg==0){
if(sum(boy[i].hi)>0){
ans++;
update(boy[i].hi,-1);
}
}
printf("%d\n",ans);
}
return 0;
}