出现了!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]<<" ";
  }
}

 

posted @ 2020-11-03 17:16  我要就问一就问一句  阅读(55)  评论(0)    收藏  举报