[NOIP2017]图书管理员

1.题目

题目链接

题号:NC16422
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述
图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个正整数。

每位借书的读者手中有一个需求码,这个需求码也是一个正整数。如果一本书的图书编码恰好以读者的需求码结尾,那么这本书就是这位读者所需要的。

小 D 刚刚当上图书馆的管理员,她知道图书馆里所有书的图书编码,她请你帮她写一个程序,对于每一位读者,求出他所需要的书中图书编码最小的那本书,如果没有他需要的书,请输出-1。

输入描述:

输入的第一行,包含两个正整数 n 和 q,以一个空格分开,分别代表图书馆里书的数量和读者的数量。 接下来的 n
行,每行包含一个正整数,代表图书馆里某本书的图书编码。 接下来的 q
行,每行包含两个正整数,以一个空格分开,第一个正整数代表图书馆里读者的需求码的长度,第二个正整数代表读者的需求码。

输出描述:
输出有 q 行,每行包含一个整数,如果存在第 i 个读者所需要的书,则在第 i 行输出第 i 个读者所需要的书中图书编码最小的那本书的图书编码,否则输出-1。

示例1

输入
5 5
2123
1123
23
24
24
2 23
3 123
3 124
2 12
2 12

输出
23
1123
-1
-1
-1

说明

第一位读者需要的书有 2123、1123、23,其中 23 是最小的图书编码。 第二位读者需要的书有 2123、1123,其中 1123
是最小的图书编码。 对于第三位,第四位和第五位读者,没有书的图书编码以他们的需求码结尾,即没有他们需要的书,输出-1。

备注:
对于 20%的数据,1 ≤ n ≤ 2。 另有 20%的数据,q= 1。
另有 20%的数据,所有读者的需求码的长度均为1。
另有 20%的数据,所有的图书编码按从小到大的顺序给出。
对于 100%的数据,1≤n ≤1,000,1 ≤ q ≤ 1,000,所有的图书编码和需求码均不超过 10,000,000。

2.分析

暴力遍历
难点在于如何判断成功与否找到书籍

3.代码

✔第一次:每个读者依次寻找,开多个数组存储,会造成空间的极大浪费

#include <stdio.h>
#include <math.h>

int SearchMin(int a[1000],int len)
{
    int i,j,MIN=a[0];
    for(i=0;i<len;i++)
    {
        if(a[i]<MIN)
            MIN=a[i];   //记录最小值
    }
    return MIN;
}

int SearchBook(int book[1000],int signal,int sz,int length)    //传入书籍 书籍数量 码 码长
{
    int i,k=0,count=0,FindSignal[1000];
    for(i=0;i<sz;i++)   //依次遍历n本书
    {
        if(signal>book[i])
            continue;
        else if(signal==book[i])    //记录找到的书,便于输出最小的值
        {
            FindSignal[k++]=book[i];
            count++;
        }
        else
        {
            int temp=pow(10,length);
            int TEMP=(book[i]-signal)%temp;
            if(TEMP==0)
            {
                FindSignal[k++]=book[i];
                count++;
            }
        }
    }
    
    if(count==0)   //未找到
        return -1;
    else
    {
        return SearchMin(FindSignal,count);
    }
}

int main()
{
    int n,q; 
    int i,j,k,Book[1000],Length[1000],Signal[1000];
    scanf("%d %d",&n,&q);   //输入书的数量 和 读者数量
    
    for(i=0;i<n;i++)
        scanf("%d",&Book[i]);   //记录书籍
    for(j=0;j<q;j++)
        scanf("%d %d",&Length[j],&Signal[j]); //记录长度 和 码
    
    for(k=0;k<q;k++)    //每个读者依次查找
           printf("%d\n",SearchBook(Book,Signal[k],n,Length[k]));
    
    return 0;
}

在这里插入图片描述

✔第二次:使用qsort函数

qsort函数

#include <stdio.h>          //注意i,j的顺序别写错了
#include <math.h>
#include <stdlib.h>
int cmp(const void *x,const void *y)    //从小到大排序
{
    return *(int *)x-*(int *)y;
}
int main()
{
    int n,q;
    int i,j;
    int flag=0;
    int Books[1000],Length[1000],Numbers[1000];
    scanf("%d %d",&n,&q);    //输入书籍数量和读者数量
    
    for(i=0;i<n;i++)
        scanf("%d",&Books[i]);   //输入书籍号码
    
    for(j=0;j<q;j++)
        scanf("%d %d",&Length[j],&Numbers[j]);  //输入长度,索书号
    
    qsort(Books,n,sizeof(int),cmp);  //将Books数组排序
    
    for(i=0;i<q;i++)        //一共q个读者
    {
        flag=0;
        int temp= pow(10,Length[i]);
        for(j=0;j<n;j++)
        {
            if(Books[j]%temp==Numbers[i])    //余数字的最后几位检验是否相同
            {
                printf("%d\n",Books[j]);
                flag=1;
                break;
            }
        }
        
        if(!flag)
            printf("%d\n",-1);

    }
    return 0;
}

在这里插入图片描述

4.总结

数组的灵活运用
库函数的使用

5.更新日志

2022.3.21 整理

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值