题目描述
莫斯科正在举办一个大型国际会议,有n个来自不同国家的科学家参会。
每个科学家都只懂得一种语言。
为了方便起见,我们把世界上的所有语言用1到$10^9$之间的整数编号。
在会议结束后,所有的科学家决定一起去看场电影放松一下。
他们去的电影院里一共有m部电影正在上映,每部电影的语音和字幕都采用不同的语言。
对于观影的科学家来说,如果能听懂电影的语音,他就会很开心;如果能看懂字幕,他就会比较开心;如果全都不懂,他就会不开心。
现在科学家们决定大家看同一场电影。
请你帮忙选择一部电影,可以让观影很开心的人最多。
如果有多部电影满足条件,则在这些电影中挑选观影比较开心的人最多的那一部。
输入格式
第一行输入一个整数n,代表科学家的数量。
第二行输入n个整数$a1,a2…an$,其中ai表示第i个科学家懂得的语言的编号。
第三行输入一个整数m,代表电影的数量。
第四行输入m个整数$b1,b2…bm$,其中bi表示第i部电影的语音采用的语言的编号。
第五行输入m个整数$c1,c2…cm$,其中ci表示第i部电影的字幕采用的语言的编号。
请注意对于同一部电影来说,$bi≠ci$。
同一行内数字用空格隔开。
输出格式
输出一个整数,代表最终选择的电影的编号。
如果答案不唯一,输出任意一个均可。
数据范围
$1≤n,m≤200000,$
$1≤ai,bi,ci≤10^9$
样例
输入样例:
3
2 3 2
2
3 2
2 3
输出样例:
2
离散化+排序
这道题目是一道离散化的好题,因为我们这里的语言,是非常的分散,所以我们可以把他们汇聚在一起,也就是重新定义这些语言,重新标号$1,2,3,…,n$。
这道题目统计方面,因为时间限制非常严格,所以动用了C++11的哈希级别map,和手动开O2的神仙操作吗,具体看代码吧。懒惰病发作
还要记得位运算|的运算级别是小于<<的.
C++ 代码
#include <bits/stdc++.h>
using namespace std;
#pragma G++ optimize (3)//开了O3
#pragma C++ optimize (3)
#define fir(i,a,b) for (int i=a;i<=b;i++)
#define pii pair<int,int>
const int N=200100;
int n,m,sc[N],lan;
unordered_map<int,int> p,q;
//p记录语言是否出现过,q记录这个语言出现了多少次
//p就是这个语言的离散化.q就是离散化后的语言出现次数.
pii mv[N],mv_ans[N];
int cmp(pii a,pii b)
{
if (a.first==b.first)
return a.second>b.second;
return a.first>b.first;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
fir(i,1,n)
{
cin>>sc[i];
if (p[sc[i]]==0)
{
p[sc[i]]=(++lan);
sc[i]=lan;
}
else
sc[i]=p[sc[i]];
q[sc[i]]++;
}
cin>>m;
fir(i,1,m)
{
cin>>mv[i].first;
mv[i].first=q[p[mv[i].first]];
}
fir(i,1,m)
{
cin>>mv[i].second;
mv[i].second=q[p[mv[i].second]];//统计这个语言出现的次数.
mv_ans[i]=mv[i];
}
sort(mv+1,mv+1+m,cmp);
fir(i,1,m)
if (mv_ans[i]==mv[1])//找排序前的下标.
{
cout<<i;
break;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize (2)
#pragma G++ optimize (2)
const int N=200100;
struct node
{
int a,b,x;
} ans2[N];
int n,m,i,j,k,cnt,pos[N];
unordered_map<int,int> p,sum;
int cmp(node aa,node bb)
{
if (aa.a==bb.a)
return aa.b>bb.b;
return aa.a>bb.a;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
for (i=1;i<=n;i++)
{
cin>>pos[i];
if (!p[pos[i]])
p[pos[i]]=(++cnt),pos[i]=cnt;
else
pos[i]=p[pos[i]];
sum[pos[i]]++;
}
cin>>m;
for (i=1;i<=m;i++)
{
int x;
cin>>x;
x=p[x];
ans2[i].a=sum[x];
ans2[i].x=i;
}
for (i=1;i<=m;i++)
{
int x;
cin>>x;
x=p[x];
ans2[i].b=sum[x];
ans2[i].x=i;
}
sort(ans2+1,ans2+1+m,cmp);
cout<<ans2[1].x;
return 0;
}
作者:秦淮岸~灯火阑珊
链接:https://www.acwing.com/activity/content/code/content/20800/
来源:AcWing
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
代码2
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize (2)
#pragma G++ optimize (2)
#define fir(i,a,b) for (int i=a;i<=b;i++)
#define pii pair<int,int>
const int N=200100;
int n,m,sc[N],lan;
unordered_map<int,int> p,q;
pii mv[N],mv_ans[N];
int cmp(pii a,pii b)
{
if (a.first==b.first)
return a.second>b.second;
return a.first>b.first;
}
int main()
{
ios::sync_with_stdio(false);
cin>>n;
fir(i,1,n)
{
cin>>sc[i];
if (p[sc[i]]==0)
{
p[sc[i]]=(++lan);
sc[i]=lan;
}
else
sc[i]=p[sc[i]];
q[sc[i]]++;
}
cin>>m;
fir(i,1,m)
{
cin>>mv[i].first;
mv[i].first=q[p[mv[i].first]];
}
fir(i,1,m)
{
cin>>mv[i].second;
mv[i].second=q[p[mv[i].second]];
mv_ans[i]=mv[i];
}
sort(mv+1,mv+1+m,cmp);
fir(i,1,m)
if (mv_ans[i]==mv[1])
{
cout<<i;
break;
}
return 0;
}
大佬们,什么是离散化?
其实我感觉这道题是搜索吧~遍历一遍得出最大的就可以了,是O(n),sort不管怎么样复杂度是O(nlogn) OwO
妙啊,自己想的时候乱的不行…
大佬,我没用离散化 时间还提升了1/3, 这道题的最优解要不要用离散化呢? 或者说这道题用离散化的意义在哪里呢?
https://www.acwing.com/activity/content/code/content/119386/
(劳烦大佬们点评一下,鄙人自知不如勿喷)
代码结构美,比我的代码不知道高明到哪里去了.
大佬,我这里一直有个疑问就是,第一个代码里面为什么要开两个map,我的代码里面只用一个map,把离散化的过程包括在里面了。然后我复制您的代码比较了一下效率,您的代码1800ms,我这里的话1200ms,
您的代码棒棒哒.我这个代码太丑了.
我来借个楼,离散化版代码看过来~AcWing 103. 电影
大佬,你的代码不开臭氧也过了
这样吗?大佬比我RP高
大佬,用map比同数组有什么优势吗
map省内存,是红黑树的封装,不过查询复杂度是$log(n)$,你可以认为map就是特殊的哈希算法.
感谢大佬
老哥我看到一个可以在noip环境用的O(1)map,是真的吗https://www.luogu.org/blog/yihan/unordered
CCF什么允许C11了?我这里用的就是这个C11特性的容器.我在考试的时候,只使用了Map,当然你可以用虚拟机装一个CCF官方指定阉割版Ubantu系统,然后写下代码后自己跑一遍,如果过了,那么就是没有问题的.
听说是奇技淫巧,
#include[HTML_REMOVED]
#include[HTML_REMOVED]
#include[HTML_REMOVED]
using namespace std;
using namespace tr1;
unordered_set[HTML_REMOVED] S1;
unordered_multiset[HTML_REMOVED] S2;
unordered_map[HTML_REMOVED] M;
int main(){
S1.insert(6);
S2.insert(7);
M[233333] = 666666;
cout << M[233333];
}
#includetr1/unordered_set
#includetr1/unordered_map
#includeiostream
是的(=^^=)
老哥你试试在cf交一下,我交了你的代码T掉了
我开了各种优化,卡常卡过去的,CF可能卡常效果不好.
因为我没有使用离散化算法,我只是用map卡常.所以一个log级别的复杂度,CF过不了.
woc 老哥 unordered_map 改 map cf跑了700+ms
这是什么恐怖操作啊!我这个是C++11的$O(1)$操作啊,按理说应该比map快啊,怎么换成map反而700+ms了
玄学操作啊.
https://zh.cppreference.com/w/cpp/container/unordered_map/operator_at
复杂度
平均情况:常数,最坏情况:与大小成线性。怕是遇到了最坏情况?
是的.QwQ,数据强悍
丧心病狂强悍的数据。。。(汗hh
cf上随手hack一下unordered_map把它卡成O(n)已经是普遍现象了……