【题目链接】

ybt 1415:【17NOIP普及组】图书管理员
洛谷 P3955 [NOIP2017 普及组] 图书管理员

【题目考点】

1. 枚举

2. 二分

【解题思路】

解法1:枚举

对于每个读者,需求码长度为len,需求码为code,图书编码存入book数组。
枚举所有图书编码,求满足该读者需求的图书中图书编码的最小值。
这里可以预处理出一个数组p,p[i]为 1 0 i 10^i 10i。
求数值x末len位的方法:x%p[len]

  • 枚举对象:图书编码
  • 枚举范围:所有的图书
  • 判断条件:判断图书编码末len位与读者需求码code是否相同。
    求满足该读者需求的图书编码中的最小值。

复杂度: O ( q ⋅ n ) O(q\cdot n) O(q⋅n)

解法2:排序+顺序查找

可以先对book数组进行升序排序,而后对于每个读者,在book数组中顺序查找满足图书编码末len位与读者需求码code相同的第一个图书编码,该编码就是满足条件的图书编码中的最小值。
复杂度: O ( q ⋅ n ) O(q\cdot n) O(q⋅n)、

解法3:排序+二分查找

可以先对book数组进行升序排序,而后对于每个读者,在book数组中二分查找满足图书编码末len位与读者需求码code相同的第一个图书编码。这就要求图书编码关于末len位有序(如果末len位相同,那么图书编码小的排在前)。
题目要求图书编码不超过 1 0 7 10^7 107,因此对图书编码分别按照:末1位,末2位,…,末7位升序进行7次排序,得到7个有序序列。按照末i位排序得到的有序序列为b[i]

如果要找满足图书编码末len位与读者需求码code相同的第一个图书编码,那么就在b[len]数组中二分查找末len位大于等于code的最小值。如果该最小值末len位与code相同,那么输出该最小值,否则输出-1。

得到7个有序序列b[1]~b[7]的复杂度为 O ( q ⋅ l o g q ) O(q\cdot log q) O(q⋅logq)
对于每个读者查找图书编码的复杂度为 O ( n ⋅ l o g q ) O(n\cdot log q) O(n⋅logq)
整体复杂度: O ( ( q + n ) ⋅ l o g ( q ) ) O((q+n)\cdot log(q)) O((q+n)⋅log(q))

【题解代码】

解法1:枚举

#include <bits/stdc++.h>
using namespace std;
#define N 1005
#define INF 0x3f3f3f3f
int book[N], p[10];//p[i]:10^i的值
void initP()
{p[0] = 1;for(int i = 1; i <= 7; ++i)//图书编码和需求码都不大于10^7,所以最大用到10^7 p[i] = p[i-1]*10;
}
int main()
{initP();int n, q, len, code;cin >> n >> q;for(int i = 1; i <= n; ++i)cin >> book[i];//book[i]:第i本书的图书编码 for(int i = 1; i <= q; ++i){cin >> len >> code;int minCode = INF;for(int j = 1; j <= n; ++j)if(book[j]%p[len] == code)minCode = min(minCode, book[j]);cout << (minCode == INF ? -1 : minCode) << endl;}return 0;
}

解法2:排序+顺序查找

#include <bits/stdc++.h>
using namespace std;
#define N 1005
int book[N], p[10];//p[i]:10^i的值
void initP()
{p[0] = 1;for(int i = 1; i <= 7; ++i)//图书编码和需求码都不大于10^7,所以最大用到10^7 p[i] = p[i-1]*10;
}
int main()
{initP();int n, q, len, code;cin >> n >> q;for(int i = 1; i <= n; ++i)cin >> book[i];//book[i]:第i本书的图书编码 sort(book+1, book+1+n);//升序排序 for(int i = 1; i <= q; ++i){cin >> len >> code;bool isFound = false;for(int j = 1; j <= n; ++j){if(book[j]%p[len] == code){cout << book[j] << endl;isFound = true;break;}}if(isFound == false)cout << -1 << endl;}return 0;
}

解法3:排序+二分查找

  • 写法1:设多个函数 手写二分查找
#include <bits/stdc++.h>
using namespace std;
#define N 1005
int n, q, b[8][N], book[N], p[10];//p[i]:10^i的值 b[i]:book按照cmpi比较得到的有序序列
void initP()
{p[0] = 1;for(int i = 1; i <= 7; ++i)//图书编码和需求码都不大于10^7,所以最大用到10^7 p[i] = p[i-1]*10;
}
//cmpl:a、b的末l位先比较,小的排在前。如果相等,a、b中较小的排在前。
bool cmp1(int a, int b)
{return a%10 == b%10 ? a < b : a%10 < b%10;
}
bool cmp2(int a, int b)
{return a%100 == b%100 ? a < b : a%100 < b%100;
}
bool cmp3(int a, int b)
{return a%1000 == b%1000 ? a < b : a%1000 < b%1000;
}
bool cmp4(int a, int b)
{return a%10000 == b%10000 ? a < b : a%10000 < b%10000;
}
bool cmp5(int a, int b)
{return a%100000 == b%100000 ? a < b : a%100000 < b%100000;
}
bool cmp6(int a, int b)
{return a%1000000 == b%1000000 ? a < b : a%1000000 < b%1000000;
}
bool cmp7(int a, int b)
{return a%10000000 == b%10000000 ? a < b : a%10000000 < b%10000000;
}
void initB()
{for(int i = 1; i <= 7; ++i)memcpy(b[i], book, sizeof(book));//先复制book到b[i]sort(b[1]+1, b[1]+1+n, cmp1); sort(b[2]+1, b[2]+1+n, cmp2);sort(b[3]+1, b[3]+1+n, cmp3);sort(b[4]+1, b[4]+1+n, cmp4);sort(b[5]+1, b[5]+1+n, cmp5);sort(b[6]+1, b[6]+1+n, cmp6);sort(b[7]+1, b[7]+1+n, cmp7);
}
int main()
{initP();int len, code;cin >> n >> q;for(int i = 1; i <= n; ++i)cin >> book[i];//book[i]:第i本书的图书编码 initB(); for(int i = 1; i <= q; ++i){cin >> len >> code;int l = 1, r = n, m;//二分查找b[len]中模p[len]后大于等于code的最小值 while(l < r){m = (l+r)/2;if(b[len][m]%p[len] >= code)r = m;elsel = m+1;}if(b[len][l]%p[len] == code)//如果找到的图书编号b[len][mi]的末len位就是要找的code cout << b[len][l] << endl;elsecout << -1 << endl;}return 0;
}
  • 写法2:使用lambda表达式,lower_bound函数
#include <bits/stdc++.h>
using namespace std;
#define N 1005
int n, q, b[8][N], book[N], p[10];//p[i]:10^i的值 b[i]:book按照cmpi比较得到的有序序列
void init()
{p[0] = 1;for(int i = 1; i <= 7; ++i) {p[i] = p[i-1]*10;//图书编码和需求码都不大于10^7,所以最大用到10^7memcpy(b[i], book, sizeof(book));//复制book到b[i]sort(b[i]+1, b[i]+1+n, [i](int a, int c)//用lambda表达式来写比较函数,捕获使用外面的变量i {return a%p[i] == c%p[i] ? a < c : a%p[i] < c%p[i];});}
}
int main()
{int len, code;cin >> n >> q;for(int i = 1; i <= n; ++i)cin >> book[i];//book[i]:第i本书的图书编码 init();for(int i = 1; i <= q; ++i){cin >> len >> code;int m = lower_bound(b[len]+1, b[len]+1+n, code, [len](int a, int c){return a%p[len] < c%p[len];}) - b[len];if(b[len][m]%p[len] == code)//如果找到的图书编号b[len][mi]的末len位就是要找的code cout << b[len][m] << endl;elsecout << -1 << endl;}return 0;
}

信息学奥赛一本通 1415:【17NOIP普及组】图书管理员 | 洛谷 P3955 [NOIP2017 普及组] 图书管理员相关推荐

  1. 信息学奥赛一本通 1414:【17NOIP普及组】成绩 | 洛谷 P3954 [NOIP2017 普及组] 成绩

    [题目链接] ybt 1414:[17NOIP普及组]成绩 洛谷 P3954 [NOIP2017 普及组] 成绩 [题目考点] 1. 算术表达式 2. 自动类型转换 低精度类型与高精度类型计算结果是高 ...

  2. 洛谷P3955 [NOIP2017 普及组] 图书管理员

    题目链接 纯粹的暴力枚举,复杂度O(n2) 因为题目数据很小,所以很安全,不会超时. #include<bits/stdc++.h> using namespace std;#define ...

  3. 信息学奥赛一本通 1392:繁忙的都市(city) | 洛谷 P2330 [SCOI2005]繁忙的都市

    [题目链接] ybt 1392:繁忙的都市(city) 洛谷 P2330 [SCOI2005]繁忙的都市 [题目考点] 1. 图论 最小生成树 [解题思路] 将题目叙述转为图论概念,交叉路口为顶点,道 ...

  4. 信息学奥赛一本通 1375:骑马修栅栏(fence) | 洛谷 P2731 [USACO3.3]骑马修栅栏 Riding the Fences

    [题目链接] ybt 1375:骑马修栅栏(fence) 洛谷 P2731 [USACO3.3]骑马修栅栏 Riding the Fences [题目考点] 1. 图论:欧拉回路 欧拉回路存在的条件: ...

  5. 信息学奥赛一本通 ybt 1933:【05NOIP普及组】循环 | 洛谷 P1050 [NOIP2005 普及组] 循环

    [题目链接] ybt 1933:[05NOIP普及组]循环 洛谷 P1050 [NOIP2005 普及组] 循环 [题目考点] 1.高精度 2.数学 [解题思路] 要求最后k位的循环长度,可以从低位向 ...

  6. 信息学奥赛一本通 1937:【06NOIP普及组】数列 | 洛谷 P1062 [NOIP2006 普及组] 数列

    [题目链接] ybt 1937:[06NOIP普及组]数列 洛谷 P1062 [NOIP2006 普及组] 数列 [题目考点] 1. 数制 [解题思路] 如果k为2,那么这个数列 第1项为202^02 ...

  7. 信息学奥赛一本通 1961:【13NOIP普及组】计数问题 | 洛谷 P1980 [NOIP2013 普及组] 计数问题

    [题目链接] ybt 1961:[13NOIP普及组]计数问题 洛谷 P1980 [NOIP2013 普及组] 计数问题 [题目考点] 1. 数字拆分 [解题思路] 遍历1~n的各个数字,对每个数字做 ...

  8. 信息学奥赛一本通 1924:【03NOIP普及组】栈 | 洛谷 P1044 [NOIP2003 普及组] 栈

    [题目链接] ybt 1924:[03NOIP普及组]栈 洛谷 P1044 [NOIP2003 普及组] 栈 [题目考点] 递推.递归 栈 [解题思路]:一维递推 设数组a,a[i]表示i个数组成的数 ...

  9. 信息学奥赛一本通 1979:【18NOIP普及组】龙虎斗 | 洛谷 P5016 [NOIP2018 普及组] 龙虎斗

    [题目链接] ybt 1979: [18NOIP普及组]龙虎斗 洛谷 P5016 [NOIP2018 普及组] 龙虎斗 [题目考点] 1. long long类型使用 已知变量a, b是int类型的变 ...

最新文章

  1. vs05b2中给dataset添加表间关系
  2. 服务的默认端口_Informatica端口管理
  3. 【完成发布】Lazy Line Painter – 非常有趣的 jQuery 路径动画插件
  4. MSSQL 2000更改表和存储过程的所有者
  5. ASCII码查询及简单说明
  6. 如何用python进行数据处理?(一)
  7. 电脑耳机有声外放无声的解决方法
  8. 2022年圣诞节外贸出口热门清单 外贸进出口商品查询 贸易动力
  9. [51Nod 1035 最长的循环节] 循环小数的性质
  10. 只需用Shift键就能提升Mac开机速度的三个方法
  11. IKEv2的密钥计算方式
  12. 机器学习环境配置(Tesla K80安装PyTorch的全过程)
  13. 粘包现象以及如何处理粘包
  14. python实现爬虫统计学校BBS男女比例(三)数据处理
  15. 从零开始的单片机学习(四)
  16. [C语言]实现字符串从头尾分别输出字符的动画效果
  17. C#连接数据库自动生成实体类
  18. Spring高手之路——深入理解与实现IOC依赖查找与依赖注入
  19. NDN Link :利用区块链技术代替TCP/IP 通信模式
  20. 论文的总体结构及质量控制

热门文章

  1. python 条件语句 出生年月 判断星座_python学习:根据生日判断12星座
  2. 关于金山词霸的屏幕取词3
  3. React非受控组件
  4. chrome浏览器下的性能测试脚本录制
  5. mysql配置MHA集群
  6. 汽车后视镜反射率测定仪
  7. 外汇天眼:FCA 警告经纪商提防差价合约的“不良做法”
  8. Docker容器中Data volumes详解
  9. Flutter完整开发实战详解(十七、 实用技巧与填坑二)
  10. 怎么用爱问转换工具在线拆分PDF文件