[关闭]
@feiyangyang 2022-06-06T06:26:07.000000Z 字数 1860 阅读 328

图书管理员题解

题解

题目链接点我

友情提供题目:

【NOIP2017普及组正式赛】图书管理员(librarian)

题目描述
图书馆中每本书都有一个图书编码,可以用于快速检索图书,这个图书编码是一个正整数。
每位借书的读者手中有一个需求码,这个需求码也是一个正整数。如果一本书的图书编码恰好以读者的需求码结尾,那么这本书就是这位读者所需要的。
小 D刚刚当上图书馆的管理员,她知道图书馆里所有书的图书编码,她请你帮她写一个程序,对于每一位读者,求出他所需要的书中图书编码最小的那本书,如果没有他需要的书,请输出
-1 。

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

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

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

样例输出 23 1123
-1
-1
-1

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

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

这题是明明白白的数学题,只要你会尝试不暴力,就能AC

思路:
首先观察数据
5 5
2123
1123
23
24
24

2 23
3 123
3 124
2 12
2 12

23 1123 -1 -1 -1

不难发现,第一个对应的图书编码减去需求码的值为0

那么记录下:如果值为零,就进入候选区域内

第二个对应的图书编码减去需求码的值为1000

可以发现,后面0的数量等于需求码的长度

那么记录下:如果值后面为零的数量与需求码的长度相等的话,就进入候选

但 有特殊
如图书编码为105230,需求码为5030,长度为4,差值为100200,虽然0的个数相等,但也是不满足的

其余的,比如小于0的,如:-20,直接pass

好了,你已经看完了,试着动手尝试把!
完整代码
这边建议手打一下
不要直接抄哦~~~

  1. #include<stdio.h>
  2. #include<iostream>
  3. using namespace std;
  4. int n,q,x,k,o=1,l,max,minn=INT_MAX;
  5. int book_code[1001],demand,code,demand_code[1001],check_demand[1001],check[1001];
  6. bool key=0;
  7. int main()
  8. {
  9. freopen("librarian.in","r",stdin);
  10. freopen("librarian.out","w",stdout);
  11. cin>>n>>q;
  12. for(int i=1;i<=n;i++)
  13. {
  14. cin>>book_code[i];//输入图书编码
  15. }
  16. for(int i=1;i<=q;i++)
  17. {
  18. cin>>x>>code;//输入长度与需求码
  19. for(int j=1;j<=n;j++)//遍历所有图书编码
  20. {
  21. l=book_code[j]-code;//取差值
  22. if(l<0)
  23. {
  24. continue;
  25. }
  26. if(l==0)//这里是正好相等,猜测:应该为最小的
  27. {
  28. if(minn>book_code[j])//判断最小
  29. {
  30. minn=book_code[j];
  31. }
  32. continue;
  33. }
  34. while(k<x/*这里是判断0的个数*/&&l%10==0)//判断0的个数
  35. {
  36. if(l%10==0)//猜测:这个应该可以省略
  37. {
  38. k++;
  39. l/=10;
  40. }
  41. }
  42. if(k==x)//判断是否正常结束循环
  43. {
  44. if(minn>book_code[j])//判断最小
  45. {
  46. minn=book_code[j];
  47. }
  48. }
  49. k=0;
  50. }
  51. if(minn!=2147483647)//判断值有没有更新
  52. cout<<minn<<endl;
  53. else
  54. {
  55. cout<<-1<<endl;
  56. }
  57. minn=INT_MAX;
  58. }
  59. }

记得反馈哦~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注