您的位置:首页 > 编程语言 > C语言/C++

◆竞赛题目◆◇NOIP 2017 普及组◇ 图书管理员

2017-11-20 11:11 369 查看

◇NOIP 2017 普及组◇图书管理员

Description

图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个

正整数。

每位借书的读者手中有一个需求码,这个需求码也是一个正整数。如果一本书的图

书编码恰好以读者的需求码结尾,那么这本书就是这位读者所需要的。

小 D 刚刚当上图书馆的管理员,她知道图书馆里所有书的图书编码,她请你帮她写

一个程序,对于每一位读者,求出他所需要的书中图书编码最小的那本书,如果没有他

需要的书,请输出-1。

Input

第一行,包含两个正整数n 和q,以一个空格分开,分别代表图书馆里

书的数量和读者的数量。

接下来的 n 行,每行包含一个正整数,代表图书馆里某本书的图书编码。

接下来的 q 行,每行包含两个正整数,以一个空格分开,第一个正整数代表图书馆

里读者的需求码的长度,第二个正整数代表读者的需求码。

Output

有q 行,每行包含一个整数,如果存在第i 个读者所需要的书,则在第i

行输出第i 个读者所需要的书中图书编码最小的那本书的图书编码,否则输出-1。

Sample Input

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


Sample Output

23
1123
-1
-1
-1


题目解析

作为 NOIP 的第二题,它始终遵循了“一二两题像洪水”的规律,只是好像多了个前导零的坑…比如书的编号有:”0123”,”00123”,”123”,询问”123”——到底输出什么?好像输出”123”是可以的,但是按照字典序的排列,”00123”是最小的一个编号。

暂时不管这么多,就当 CCF 有良心,不出这种数据~

于是我们就可以愉快地用 int 储存书的编号了。用int就有一个很方便的地方——取它的最后n位只需要对它取模 10n−1 就可以了。由于数据给出了查询码的长度,我们调用 cmath 中的 pow() 函数计算出将要取模的数 Mod,剩下的就是枚举——只有1000的数据规模,O(n2) 的时间复杂度完全不担心超时。对于每一本书,将它的编码模一个 Mod ,如果满足得到的数与查询码相等(由于没有前导零,其实也就是相同),则满足条件。同时找到满足条件的这些书的编码中的最小值即可。这里可以作一个优化——先把书的编码 sort 排序,按小到大排,则第一个找到的满足条件的编码就是答案。

听起来很简单,不如看看代码——

AC代码(民间数据):13ms 1.1M

//Problem 2
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int Num_book,Num_reader,book[1005];
int main()
{
freopen("librarian.in","r",stdin);
freopen("librarian.out","w",stdout);
scanf("%d%d",&Num_book,&Num_reader);
for(int i=0;i<Num_book;i++) scanf("%d",&book[i]);
sort(book,book+Num_book);
for(int i=0;i<Num_reader;i++)
{
bool Find=false;
int reader,len;scanf("%d%d",&len,&reader);
int Mod=pow(10,len);
for(int j=0;j<Num_book;j++)
if(book[j]%Mod==reader)
{
Find=true;
printf("%d\n",book[j]);
break;
}
if(!Find) printf("-1\n");
}
return 0;
}


The End

Thanks for reading!

-Lucky_Glass
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ NOIP-2017