题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5979
题意
前面都是废话,题目从图片下面的第一段话开始!
n个男生,m个女生,给出男生的身高ai,女生的身高bi,任何两个人的身高都不相同。
如果p=0表示ta想要和比ta身高矮的人配对,p=1表示ta想要和比ta身高高的人配对。
求异性之间成功配对的对数。
解题思路
两个人之间内能配对一定要满足,x想要高的,y想要矮的,且y比x高。
对男生身高排序,p不同时p=0的排在前面,相同时身高按升序排,读入的时候记录p=0的个数cnt0。
对女生身高排序,p不同时p=1的排在前面,相同时身高按升序排,读入的时候记录p=1的个数cnt1。
接下来模拟匹配过程就ok了。注意:一定是两个p不同的异性之间比较身高!
时间复杂度O(nlogn)
ac代码
男女身高分别排序
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <set>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <sstream>
#define maxn 100005
typedef long long ll;
using namespace std;
struct node{
ll height;
ll want;
}a[maxn],b[maxn];//a 男生,b 女生
bool cmpa(node a,node b)//男生先排0
{
return a. want==b.want?a.height<b.height:a.want<b.want;
}
bool cmpb(node a,node b)//女生先排1
{
return a.want==b.want?a.height<b.height:a.want>b.want;
}
int main()
{
//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
ll t;
scanf("%lld",&t);
while(t--)
{
ll n,m,cnt1=0,cnt0=0,ans=0;//a-cnt0,b-cnt1
//读入
scanf("%lld %lld",&n,&m);
for(ll i=0;i<n;i++)
scanf("%lld",&a[i].height);
for(ll i=0;i<m;i++)
scanf("%lld",&b[i].height);
for(ll i=0;i<n;i++)
{
scanf("%lld",&a[i].want);
if(!a[i].want) cnt0++;
}
for(ll i=0;i<m;i++)
{
scanf("%lld",&b[i].want);
if(b[i].want) cnt1++;
}
//排序
sort(a,a+n,cmpa);
sort(b,b+m,cmpb);
//匹配
for(ll i=0,j=0;i<cnt0 && j<cnt1; )//i-a0,j-b1,男高女矮
{
if(a[i].height>b[j].height)
{
ans++;
i++;j++;
}
else i++;//男的不够高,往下找高的
}
for(ll i=cnt0,j=cnt1;i<n && j<m; )//男矮女高
{
if(a[i].height<b[j].height)
{
ans++;
i++;j++;
}
else j++;//女的不够高
}
printf("%lld\n",ans);
}
return 0;
}
男女身高同样的排序方法,男女分别记录p=0的个数(from:https://blog.csdn.net/sdau_fangshifeng/article/details/89300201)
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<iostream>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<set>
#include<vector>
using namespace std;
#define PI acos(-1.0)
#define pppp cout<<endl;
#define EPS 1e-8
#define LL long long
#define ULL unsigned long long //1844674407370955161
#define INT_INF 0x3f3f3f3f //1061109567
#define LL_INF 0x3f3f3f3f3f3f3f3f //4557430888798830399
// ios::sync_with_stdio(false);
// 那么cin, 就不能跟C的 scanf,sscanf, getchar, fgets之类的一起使用了。
const int dr[]= {0, 0, -1, 1, -1, -1, 1, 1};
const int dc[]= {-1, 1, 0, 0, -1, 1, -1, 1};
int read()//输入外挂
{
int ret=0, flag=0;
char ch;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
ret = ch - '0';
while((ch=getchar())>='0'&&ch<='9')
ret=ret*10+(ch-'0');
return flag ? -ret : ret;
}
const int maxn=100050;
struct node
{
int heigh;
int select;
} a[maxn],b[maxn];
bool cmp(node x,node y) //排序,现把0放在前面,1放在后面
{
if(x.select==y.select)
return x.heigh<y.heigh;
else
return x.select<y.select;
}
int main()
{
freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
int n,m;
scanf("%d%d",&n,&m); //全部初始化为未匹配点
for(int i=0; i<n; ++i)
scanf("%d",&a[i].heigh);
for(int i=0; i<m; ++i)
scanf("%d",&b[i].heigh);
int cnt1=0;//男生0的个数
int cnt2=0;//女生0的个数
for(int i=0; i<n; ++i)
{
scanf("%d",&a[i].select);
if(!a[i].select)
++cnt1;
}
for(int i=0; i<m; ++i)
{
scanf("%d",&b[i].select);
if(!b[i].select)
++cnt2;
}
sort(a,a+n,cmp);
sort(b,b+m,cmp);
int num=0;
int j=cnt2;
for(int i=0; i<cnt1; ++i) //男生高,女生矮
{
if(a[i].heigh>b[j].heigh)
{
num++;
j++;
}
if(j>=m)
break;
}
j=cnt1;
for(int i=0; i<cnt2; ++i) //女生高,男生矮
{
if(b[i].heigh>a[j].heigh)
{
num++;
j++;
}
if(j>=n)
break;
}
printf("%d\n",num);
}
return 0;
}