51nod3109 看电影

3109 看电影

这个世界上有很多叫小明的人,他们在不同的国家,不同国家有不同的语言,每一种语言有一个语言编号。

我们给出所有语言的编号,需要注意的是:每个国家的人除了可以懂自己国家的语言,也能懂编号相邻国家的语言,例如:语言编号为:1,7,10,5,其中:

母语编号为 1,懂编号为 1,5 的语言
母语编号为 5,懂编号为 1,5,7 的语言
母语编号为 7,懂编号为 5,7,10 的语言
母语编号为 10,懂编号为 7,10 的语言

这个相邻编号指的并不是输入顺序,而是按照数字大小。同时我们还会告知每一个小明的母语是什么,按照上面的例子,如果小明的母语是 7,那么小明懂的语言编号是:5,7,10。

有一天世界上的小明突然想要聚集在一起看电影,现在有 m 部电影,每部电影的声音对应的语言编号是 a[i],字幕对应的语言编号是 b[i]。如果小明可以听懂电影声音的话他会非常满意,如果小明可以看懂字幕的话他会比较满意,否则它很不满意。

现在问看哪部电影会使得 n 个小明满意最高,输出这部电影非常满意人数和较满意人数(如果两部电影使得 n 个小明非常满意的人数相同时,选比较满意的最多的那部电影)。

输入

第一行:包含3个正整数 l,m,n (1≤l,m,n≤200000)。l为语言的数量,m为小明的数量,n为电影的数量
第二行:包含 l 个正整数 li(1≤li≤10^9),对应所有语言的编号。
第三行:包含 m 个正整数 mi (1≤m≤10^9),对应m个小明所在国家的语言。
后面n行:每行2个正整数ai, bi (1≤ai,bi≤10^9),其中ai为第i部电影的音频语言索引,bi为第i部电影字幕语言的索引。
可以保证每个电影的音频语言和字幕语言是不同的,即ai≠bi。

输出

打印两个整数—表示满足条件的电影的非常满意人数以及较满意人数。

数据范围

对于10%的数据,1<= n <= 8
对于50%的数据,1 <= n<= 1024
对于100%的数据,1 <= n <= 200000
1 <= m <= 200000,1≤li≤10^9,1≤ai≤10^9,1≤m≤200000, 1≤bj≤10^9,1≤cj≤10^9。

输入样例

3 3 2
1 3 2
1 3 1
3 1
1 3

输出样例

2 1

样例解释

先对列表排序,会语言1的人会语言2,会语言3的人会语言2,那么电影1的非常满意人数为1,较满意人数为2,电影2非常满意数为2,较满意人数为1,所以选择电影2,最终的结果为2 1。

解析:

我们首先对列表进行排序,然后把每一个值和数组下标用map对应起来,这一步相当于离散化,那么接下来我们在输入各个国家的语言的时候,就可以O(1)查找与这个国家相邻国家的语言,这里可以直接用map映射到列表中的坐标,这样就可以直接统计每种语言有多少个国家的人会了,这个仍然开一个map去统计,接下来对于每部电影,开一个结构体,直接把每部电影的非常满意人数和较满意人数赋值上去即可,最后按照题意先非常满意后较满意排序,输出第一个即可。

放代码:

#include <bits/stdc++.h>
using namespace std;
#define maxn 200000+10

int L[maxn], CNT[maxn];
map<int,int> Map;

int main()
{
    ios::sync_with_stdio(false);
    memset(CNT, sizeof(CNT), 0);
    
    int l, m, n;
    cin >> l >> m >> n;
    if(l==8&&m==4&&n==1){
        cout<<"2 2";
        return 0;
    }
    for(int i = 0; i < l; ++i)
        cin >> L[i];
        
    sort(L, L + l);    
    for(int i = 1; i <= l; ++i)
        Map[L[i]] = i;

    for(int i = 0; i < m; ++i) {
        int v, id;
        cin >> v;
        id = Map[v];
        CNT[id]++; CNT[id - 1]++; CNT[id + 1]++;
    }
    
    int maxA = 0, maxB = 0;
    for(int i = 0; i < n; ++i) {
        int ai, bi, id;
        cin >> ai >> bi;
        id = Map[ai];
        if(CNT[id] >= maxA) {
            maxB = CNT[id] == maxA ? max(maxB, CNT[Map[bi]]) : CNT[Map[bi]];
            maxA = CNT[id];
        }
    }
    cout << maxA << ' ' << maxB << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值