浙大校赛--A(树状数组+离散化)

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;
}

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/89322075