当前位置: 代码迷 >> 综合 >> [NOIP2017]图书管理员
  详细解决方案

[NOIP2017]图书管理员

热度:97   发布时间:2023-12-04 12:15:43.0

[NOIP2017]图书管理员

  • 1.题目
  • 2.分析
  • 3.代码
    • ?第一次:每个读者依次寻找,开多个数组存储,会造成空间的极大浪费
    • ?第二次:使用qsort函数
  • 4.总结
  • 5.更新日志

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 整理