• 2022牛客多校10 I-Yet Another FFT Problem?(鸽巢原理)


     

    题目大意:给定一个n,m,分别代表a数组和b数组的长度,接下来给出a数组和b数组,问是否存在i,j,k,l满足1<=i,j<=n,1<=k,l<=m,i!=j,k!=l使得|aj-ai|=|bl-bk|,如果存在则输出,否则输出-1.

    解题思路:由|aj-ai|=|bl-bk|交换左右两边可以去掉绝对值得到aj+bk=bl+ai,又因为0<=ai,bi<=1e7,所以我们可以开长度为2e7的数组作为map映射a,b两个数组中每个值的位置,以及两个数的加和==temp时两个数字ai和bl,在两个数组中分别出现的位置,具体的做法就是遍历a,b两个数组中所有不同的数字,并记录两个数的加和,如果两个数的加和在之前已经出现过,那么答案就是当前两个数的位置和之前出现相同加和时两个数的位置,这里我们需要注意一点就是a,b两个数组必须去重之后才能遍历两个数组找加和,因为如果不去重的话两个数组的长度都是1e6两重循环会超时的,但是由于我们去重了,所以两个数的加和最多有2e7种情况,所以复杂度就不会超了,但是我们还要考虑到一种情况就是在a,b两个数组中可能会有ai=aj,bl=bk,所以在去重之前我们要特判一下这种情况。最后也是说一点注意事项,前面说到要用数组来模拟map的功能,主要是因为map会比数组要慢,我一开始就是用的map结果超时了,但是改成数组之后就过了。

    上代码:

    1. #include <iostream>
    2. #include <cstring>
    3. #include <cstdio>
    4. #include <algorithm>
    5. #include <map>
    6. #include <vector>
    7. using namespace std;
    8. const int N=2e7+10;
    9. int n,m,a[N],b[N];
    10. int mpa1[N],mpa2[N],mpb1[N],mpb2[N],mp[N];
    11. vector<int>ca,cb;
    12. int main()
    13. {
    14. scanf("%d %d",&n,&m);
    15. int posa1=0,posa2=0,posb1=0,posb2=0;
    16. for(int i=1;i<=n;i++)
    17. {
    18. scanf("%d",&a[i]);
    19. if(mpa1[a[i]])
    20. {
    21. posa1=mpa1[a[i]];
    22. posa2=i;
    23. }
    24. else
    25. {
    26. mpa1[a[i]]=i;
    27. ca.push_back(a[i]);
    28. }
    29. }
    30. for(int i=1;i<=m;i++)
    31. {
    32. scanf("%d",&b[i]);
    33. if(mpb1[b[i]])
    34. {
    35. posb1=mpb1[b[i]];
    36. posb2=i;
    37. }
    38. else
    39. {
    40. mpb1[b[i]]=i;
    41. cb.push_back(b[i]);
    42. }
    43. }
    44. sort(ca.begin(),ca.end());
    45. sort(cb.begin(),cb.end());
    46. ca.erase(unique(ca.begin(),ca.end()),ca.end());
    47. cb.erase(unique(cb.begin(),cb.end()),cb.end());
    48. if(posa1&&posb1)
    49. {
    50. cout<<posa1<<" "<<posa2<<" "<<posb1<<" "<<posb2<<endl;
    51. return 0;
    52. }
    53. int flag=0;
    54. for(int i=0;i<ca.size();i++)
    55. for(int j=0;j<cb.size();j++)
    56. {
    57. int temp=ca[i]+cb[j];
    58. if(mpa2[temp])
    59. {
    60. cout<<mpa1[ca[i]]<<" "<<mpa2[temp]<<" "<<mpb1[cb[j]]<<" "<<mpb2[temp];
    61. flag=1;
    62. return 0;
    63. }
    64. mpa2[temp]=mpa1[ca[i]];
    65. mpb2[temp]=mpb1[cb[j]];
    66. }
    67. if(flag==0)
    68. cout<<"-1"<<endl;
    69. return 0;
    70. }

     

  • 相关阅读:
    程序员工作5年,还是个中级程序员,如何再快速晋升?
    慢慢欣赏linux 进程unattended-upgr CPU占用率过高定位
    工业5G路由器驱动矿山无人值守及井下监控数据传输
    pdd.order.list.get拼多多店铺订单列表查询接口(拼多多店铺订单详情接口,订单明文接口,订单解密接口,订单插旗接口,订单备注接口)代码对接教程
    Android init.rc 解析
    【SRE】MySQL8使用方式
    CAP&Base理论
    三分钟了解var const let 区别
    赋能心理大模型,景联文科技推出高质量心理大模型数据库
    再次捕获!重保期间拦截针对Coremail的钓鱼攻击
  • 原文地址:https://blog.csdn.net/weixin_54562114/article/details/126455140