求助(样例能过(自己的dev和洛谷的IDE都能过),但是提交前四个re)

P2249 【深基13.例1】查找

202312904209hyt @ 2023-12-15 15:07:17


your codes...
```#include<stdio.h>
long long n[1000001],m[1000001],i,a,s=0;
int main()
{
    scanf("%lld%lld",&n[0],&m[0]);
    for(i=1;i<=n[0];i++)
    {
        scanf("%lld",&n[i]);
    }
    for(i=1;m[0]>0;m[0]--)
    {
        scanf("%lld",&a);
        for(s=0;a>=n[i];i++)
        {
            if(s==0&&a==n[i])
            {
                printf("%lld ",i);
                s=1;
            }
        }
        if(s==0)
            printf("-1 ");
    }
    return 0;
}

by Botter @ 2023-12-15 15:43:58

for(s=0;a>=n[i];i++)

这里的i会越界,题目没有说询问数组有序吧,当第一次就很大i会一直加下去


by Botter @ 2023-12-15 15:44:30

直接用二分呀


by 202312904209hyt @ 2023-12-16 14:31:10

@Botter 可是它题目说了前面的数不大于后面的数,而且你要用二分的话,也是说明数组有序的吧


by 202312904209hyt @ 2023-12-16 14:34:27

@Botter 抱歉!我刚刚理解错你的意思了!非常抱歉!现在懂了


by 202312904209hyt @ 2023-12-16 14:35:02

@Botter 当时没想到,也不太会用(꒦_꒦)


by 202312904209hyt @ 2023-12-16 14:47:27

@Botter 虽然但是 不re了,但全部wa了 (虽然样例能过)


long long n[1000001],m[1000001],i,a,s=0;
int main()
{
    scanf("%lld%lld",&n[0],&m[0]);
    for(i=1;i<=n[0];i++)
    {
        scanf("%lld",&n[i]);
    }
    for(i=1;i<=m[0];i++)
        scanf("%lld",&m[i]);
for(a=1,i=1;m[0]>0;m[0]--,a++)
    {
        for(s=0;m[a]>=n[i]&&i<=1000000;i++)
        {
            if(s==0&&m[a]==n[i])
            {
                printf("%lld ",i);
                s=1;
            }
        }
        if(s==0)
            printf("-1 ");
    }

}```

by Botter @ 2023-12-17 20:39:31

@202312904209hyt 不好意思啊,今天比赛 你的写法应该是这种,要遍历一遍n数组,但是这种O(n*m)的写法只能过两个测试点,其他的全超时 正解应该是二分查找

#include<iostream>
#include<cmath>
#include<unordered_map>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
long long n[1000001],m[1000001],i,a,s=0;
int main()
{
    scanf("%lld%lld",&n[0],&m[0]);
    for(i=1;i<=n[0];i++)
    {
        scanf("%lld",&n[i]);
    }
    for(i=1;i<=m[0];i++)
        scanf("%lld",&m[i]);
for(i=1;i <= m[0] ; i++)
    {   s = 0;
        for (int j = 1 ; j <= n[0] ; j++){
            if (s== 0 && m[i] == n[j]){
                printf("%lld " , j);
                s = 1;
                break;
            }

        }
        if (s == 0) printf("-1 ");
        // for(s=0;m[a]>=n[i]&&i<=1000000;i++)
        // {
        //  if(s==0&&m[a]==n[i])
        //  {
        //      printf("%lld ",i);
        //      s=1;
        //  }
        // }
        // if(s==0)
        //  printf("-1 ");
    }
}

by Botter @ 2023-12-17 20:40:51

@202312904209hyt 如果m数组有序你的写法应该就是正确的


by Botter @ 2023-12-17 21:16:02

@202312904209hyt

写个二分的代码,注释差不多挺详细了

#include <stdio.h> 
const int N = 1e6+10;
int a[N],n,m;
int main(){
    scanf("%d %d" , &n , &m);
    for (int i = 1 ; i <= n ; i++)
        scanf("%d" , &a[i]);
    //根据题意查找第一个大于等于  或者 小于等于的数
    while(m--){
        int x;
        scanf("%d" , &x);
        int left = 1 , right = n;
        while (left < right){
            int mid = left + (right - left >> 1); // 防止int溢出
            if (a[mid] >= x) right = mid; //查找第一个大于等于x的数 
            else left = mid+1;
        }
        //循环结束时left是指向第一个大于等于x的数,所以要特判一下 
        if (left <= right && a[left] == x) printf("%d " , left);
        else printf("-1 ");
    }
    return 0;
}

by 202312904209hyt @ 2023-12-18 22:34:17

@Botter 没事!谢谢你!!!


|