首页 > 技术文章 > CF670C Cinema(离散化)

wisdom-jie 2020-12-04 14:39 原文

 

题目大意

  有m部正在上映的电影,每部电影的语音和字幕都采用不同的语言,用一个int范围内的整数来表示语言。有n个人相约一起去看其中一部电影,每个人只会一种语言,如果一个人能听懂电影的语音,他会很高兴;如果能看懂字幕,他会比较高兴;如果语音和字幕都不懂,他会不开心。请你选择一部电影让这n个人一起看,使很高兴的人最多。若答案不唯一,则在此前提下再让比较高兴的人最多,n,m≤2*105

题解

  看到这道题首先想到用一个桶来存储这种语言的人数,每读入一名科学家的语言i就将将桶加1,但是看数据范围:1e9,开桶一定会爆空间,所以只需要用离散化来优化即可。

  先说说,离散化就是把无穷大集合中的若干个元素映射为有限集合以便于统计的方法,例如如果要排序10个1e9左右的数,那么用桶排序固然不能实现,那么离散化可以将这十个1e9的数对应成1-10再进行排序。

  在离散化过程中,可以利用lower_bound来二分查找x对应的整数,不用手写二分。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int lan[200005],py[200005],zm[200005],a[600005],b[600005],ton[600005];
int main()
{
    int n,m,i,x=0,pym=0,zmm=0,xuan;
    scanf("%d",&n);
    for(i=1;i<=n;i++)//语言 
    {
        scanf("%d",&lan[i]);
        x++;a[x]=lan[i];
    }
    scanf("%d",&m);
    for(i=1;i<=m;i++)//配音 
    {
        scanf("%d",&py[i]);
        x++;a[x]=py[i];
    }
    for(i=1;i<=m;i++)//字幕 
    {
        scanf("%d",&zm[i]);
        x++;a[x]=zm[i];
    }
    sort(a+1,a+1+n+m+m);x=0;
    for(i=1;i<=n+m+m;i++)//去重
        if(i==1||a[i]!=a[i]-1){x++;b[x]=a[i];}
    for(i=1;i<=n;i++)
    {
        lan[i]=lower_bound(b+1,b+1+n+m+m,lan[i])-b;//映射
        ton[lan[i]]++;
    }
    for(i=1;i<=m;i++)
    {
        py[i]=lower_bound(b+1,b+1+n+m+m,py[i])-b;
        zm[i]=lower_bound(b+1,b+1+n+m+m,zm[i])-b;
        if(ton[py[i]]>pym){pym=ton[py[i]];zmm=ton[zm[i]];xuan=i;}
        else if(ton[py[i]]==pym&&ton[zm[i]]>zmm){pym=ton[py[i]];zmm=ton[zm[i]];xuan=i;}
    }
    printf("%d",xuan);
    return 0;
}

推荐阅读