出现了!sort和二分混合双打!
题目描述
虽然 Miss Medusa 到了北京,领了科技创新奖,但是他还是觉得不满意。原因是:他发现很多人都和他一样获了科技创新奖,特别是其中的某些人,还获得了另一个奖项——特殊贡献奖。而越多的人获得了两个奖项,Miss Medusa就会越眼红。于是她决定统计有哪些人获得了两个奖项,来知道自己有多眼红。
输入格式
第一行两个整数 n, m,表示有 n个人获得科技创新奖,m个人获得特殊贡献奖。
第二行 n 个正整数,表示获得科技创新奖的人的编号。
第三行 m 个正整数,表示获得特殊贡献奖的人的编号。
输出格式
输出一行,为获得两个奖项的人的编号,按在科技创新奖获奖名单中的先后次序输出。
思路:
先将两组数据分别输入,然后将第三行输入的数据(贡献奖获得者的序号)进行sort排序(为二分做准备),接着就可以进行二分查找出相应创新奖的最终位置,此时再将最终位置代表的数与创新奖获得者的序号比较是否一致,一致则将其存储进答案数组,最后遍历完毕将答案数组按序输出便可;
本质上这是一道模板应用题,其sort为自带函数,而二分查找则按照之前所写的二分模板套用即可(在此题目中,由于没有重复数据,因此套用查找左边界模板或是查找右边界模板均可找到最终位置);非常要注意这题由于数据量过大,因此数组也应当开的大一些,当我开的数组只比题目所给要求大10时(即100010),有两个测试点是不能过的,而当我将数组开为1000100时,却可以将这两个测试点过掉,具体原因我也不是很清楚,下次遇见数据量较大的情况时,有条件的应该将数组开的大一些;
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
int ans[1000100];
int k=1;
signed main()
{
int n,m;
cin>>n>>m;
int a[1000100];
int b[1000100];
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
}
for(int i=1;i<=m;i++)
{
scanf("%d",&b[i]);
}
sort(b+1,b+1+m);
for(int i=1;i<=n;i++)
{
int x=a[i];
int l=1,r=min(x,m);
while(l<r)
{
int mid=l+r>>1;
if(b[mid]>=x) r=mid;
else l=mid+1;
}
if(b[l]==x)
{
ans[k++]=x;
}
}
for(int i=1;i<=k-1;i++)
{
cout<<ans[i]<<" ";
}
}

浙公网安备 33010602011771号