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

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


听起来很简单,不如看看代码——
AC代码(民间数据):13ms 1.1M

//Problem 2
#include
#include
#include
#include
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;iscanf("%d",&book[i]);
    sort(book,book+Num_book);
    for(int i=0;ibool Find=false;
        int reader,len;scanf("%d%d",&len,&reader);
        int Mod=pow(10,len);
        for(int j=0;jif(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


你可能感兴趣的:(#模拟算法,-,水题的浪潮#)