给定两个序列a和b,每个序列中可能含有重复的数字。
一个配对(i,j)是一个好配对当从第一个序列中选出一个数ai,再从第二个序列中选出一个数bj且满足ai>bj。
给出两个序列,问存在多少个好配对。
输入包含多组数据,数据第一行一个整数T,表示数据组数。(T<=5)
每组数据第一行包含两个整数n和m。(0<n,m<=105)
接下来n行,每行两个整数x和y,表示在第一个序列中有y个x。
接下来m行,每行两个整数x和y,表示在第二个序列中有y个x。(0<x<=109,0<y<=104)
对于每组数据,输出一行一个整数,表示好配对的数量
样例输入
1 2 2 3 2 4 1 3 1 2 3样例输出
10
分析:思维题。按照x从小到大排个序,然后扫一下就好。时间复杂度O(n+m)。
题目链接:http://hihocoder.com/problemset/problem/1123
代码清单:
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 100000 + 5;
struct Point {int x,y;};
bool cmp(Point a,Point b){ return a.x<b.x; }
int T;
int n,m;
Point pointa[maxn];
Point pointb[maxn];
void input(){
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d%d",&pointa[i].x,&pointa[i].y);
for(int i=0;i<m;i++)
scanf("%d%d",&pointb[i].x,&pointb[i].y);
}
ll work(){
sort(pointa,pointa+n,cmp);
sort(pointb,pointb+m,cmp);
int j=0;
ll ans=0,sum=0;
for(int i=0;i<n;i++){
for(;j<m;j++){
if(pointa[i].x>pointb[j].x)
sum+=pointb[j].y;
else break;
}
ans+=sum*pointa[i].y;
}return ans;
}
void solve(){
printf("%lld\n",work());
}
int main(){
scanf("%d",&T);
while(T--){
input();
solve();
}return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文:http://blog.csdn.net/jhgkjhg_ugtdk77/article/details/47177525