二分练习

二分练习

Time Limit: 1000MS Memory Limit: 65536KB
Submit Statistic Discuss
Problem Description

给你一个序列,然后给你m个元素,让你从序列中找出与每个元素最接近的数字输出来,如果有两个就输出两个。

Input

多组输入,第一行给你两个数n(0 < n < 10000000),m(0 < m < n),接下来是数列的n个数,然后再输入m个元素,让你找出最接近每个元素的值。如果有两个,按从小到大输出。

Output

这m个数分别输出最接近每个元素的值,组与组之间输出一个空行。
Example Input

8 4
1 2 3 4 5 6 8 11
4
9
2
7
Example Output

4
8
2
6 8
Hint

Author

lwn
二分查找,想了好久,看到师父的博客,觉得还能理解……THANKS
推荐博客

#include <bits/stdc++.h>
#define MAXN 10000000
using namespace std;
int ma[MAXN];
int f;
void search(int a, int left, int right)
{
    int i = left, j = right;
    int mid = (left + right)/2;
    while(i<j)//寻找a的左右数字
    {
        if(a==ma[mid])
        {
            printf("%d\n", ma[mid]);
            return ;
        }
        else if(ma[mid]>a)
        {
            j = mid - 1;
            mid = (i + j) / 2;
        }
        else if(ma[mid]<a)
        {
            i = mid + 1;
            mid = (i + j) / 2;
        }
    }
    if(ma[i]==a)//如果找到的这个数字和a相等,输出
    {
        printf("%d\n", ma[i]);
        return ;
    }
    if(ma[i]>a)//如果比a大
    {
        if(i==left)//如果是最左边的一个,直接输出
        {
            printf("%d\n", ma[i]);
            return ;
        }
        else//不然比较a与左右两边数字的差值,然后选择输出
        {
            if(ma[i]-a>a-ma[i-1])
            {
                printf("%d\n", ma[i-1]);
                return ;
            }
            else if(ma[i]-a<a-ma[i-1])
            {
                printf("%d\n", ma[i]);
                return ;
            }
            else
            {
                printf("%d %d\n", ma[i-1], ma[i]);
                return ;
            }
        }
    }
    else if(ma[i]<a)//如果比a小
    {
        if(i==right)//如果是最右边的,输出
        {
            printf("%d\n", ma[right]);
            return ;
        }
        else//否则,比较大小,选择输出
        {
            if(a-ma[i]>ma[i+1]-a)
            {
                printf("%d\n", ma[i+1]);
                return ;
            }
            else if(a-ma[i]<ma[i+1]-a)
            {
                printf("%d\n", ma[i]);
                return ;
            }
            else
            {
                printf("%d %d\n", ma[i], ma[i+1]);
                return ;
            }
        }
    }
}
int main()
{
    int n, m, a;
    while(~scanf("%d %d", &n, &m))
    {
        for(int i=0;i<n;i++)
            scanf("%d", &ma[i]);
        sort(ma, ma+n);//排序
        for(int i=0;i<m;i++)
        {
            scanf("%d", &a);
            f = 0;
            search(a, 0, n-1);
        }
        printf("\n");
    }
    return 0;
}

今天的比赛,我又碰到这题了,然后我用的是vector存储,然后用lower_bound()函数做的,但是奇迹般的超时了,我觉得有点不应该,然后又试了几遍,还是超时,后来比赛结束的时候,我还是不太相信,就又敲了一遍,还是超时~~~~~~~
刚刚,突然发现,我用了cin输入,改成了scanf,就A了~
我觉得自己要长个记性,啥事都忘,什么都忘,这记忆也是没谁了~

#include <bits/stdc++.h>
using namespace std;
vector<int> a;
int main()
{
    int n, m;
    while(cin>>n)
    {
        a.clear();
        cin>>m;
    for(int i=0;i<n;i++)
    {
        int x;
        scanf("%d", &x);
        a.push_back(x);
    }
    sort(a.begin(), a.end());
    while(m--)
    {
        int k;
        cin>>k;
        int p = lower_bound(a.begin(), a.end(), k) - a.begin();
        if(p>=n)
        {
            cout<<a[n-1]<<endl;
            continue;
        }
        else if(p==0)
        {
            cout<<a[0]<<endl;
            continue;
        }
        if(a[p]==k)
            cout<<a[p]<<endl;
        else
        {
            int x = a[p] - k;
            int y = k - a[p-1];
            if(x==y)
                cout<<a[p-1]<<' '<<a[p]<<endl;
            else if(x<y)
                cout<<a[p]<<endl;
            else
                cout<<a[p-1]<<endl;
        }
    }
    cout<<endl;
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值