新报数游戏

题目

蒜头君在和他的朋友们一起玩一个游戏。由于蒜头君的机智,这个游戏由蒜头君担任裁判。

首先,蒜头君会给他们一人一个编号,并且每个人的编号都不相同。接下来的每一回合,蒜头君会给一个数,编号不超过它的最大编号的人要报出自己的编号。如果没有人的编号比蒜头君给出的数要小,那么编号最小的人要报出自己的编号。每个人可以重复报号。

蒜头君会按照一个列表顺次报出每个回合的数,他的朋友们想知道每回合报出的编号应该是多少。你能帮帮他们吗?

输入格式

输入数据共 3 行。 
第一行有两个整数 n, m(1n105,1m105≤n≤105,1≤m≤105)分别表示参与游戏的蒜头君朋友的个数,和游戏的回合数。

第二行 n 个整数 ai(1ai108)ai(1≤ai≤108),表示朋友们每个人的编号。

第三行 mm 个整数 qi(1qi108)qi(1≤qi≤108),表示每回合蒜头君给的数字。

输出格式

输出共一行,输出 mm 个整数,表示每回合报出的编号。每两个整数之间有一个空格,最后一个整数后面没有空格。

样例输入

5 5
1 5 10 15 20
3 6 12 18 24

输出

1 5 10 15 20

  请使用scanf和printf进行输入和输出。 毫无疑问,你需要一个排序算法——这里你可以随意地使用任何一种方法对数据进行排序:你可以选择自己实现一种常见的排序算法(例如冒泡排序或者归并排序),同样你也可以选择使用qsort或者std::sort,这里我们不做限制。 你还需要一种效率比较高的查找算法——你可以用之前学过的折半查找算法(也叫二分查找算法)来解决这个问题。

#include<iostream>
#include<algorithm>
#define MAX 100000+10
using std::sort;
int finder(int array[],int low,int high,int target)//二分查找
{
    while(low<=high)
        {
            int mid=(low+high)/2;
            if(array[mid]>target)
                high=mid-1;
            else 
            low=mid+1;
        }
            return high;
}
int main()
{
    int n,m;
    int a[MAX]; // 朋友编号
    int q[MAX]; // 蒜头君的数字
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++) // 朋友每个人的编号
    {
        scanf("%d",&a[i]);
    }
    sort(a,a+n);
    for(int j=0;j<m;j++) // 每回合蒜头君给的数字
    {
        scanf("%d",&q[j]);
    }
    for(int k=0;k<m;k++) // 输出模块
    {
        int c=q[k];
        if(c>=a[n-1]) // 当给出的数大于最大编号时
        {
            printf("%d",a[n-1]); 
        }
        else if(c<=a[0]) // 当给出的数小于最小编号时
        {
            printf("%d",a[0]);
        }
        else // 编号不超过它的最大编号时
        {
            printf("%d",a[finder(a,0,n,c)]);
        }
        if(k!=m-1) printf(" ");
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/fuhang/p/8932967.html