hihoCoder_#1123_好配对

#1123 : 好配对

时间限制: 1000ms
单点时限: 1000ms
内存限制: 256MB

描述

给定两个序列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;
}


你可能感兴趣的:(Algorithm,ACM,hihoCoder)