3 条题解
-
0
#include <bits/stdc++.h> using namespace std; int main(){ int n,q; cin>>n>>q; int book[1001]; int len[1001]; int code[1001]; for(int i=0;i<n;i++){ cin>>book[i]; } for(int i=0;i<q;i++){ cin>>len[i]>>code[i]; } //数据读取完毕 //先把图书编码递增排序,方便找到最小的 sort(book,book+n); vector<int> p;//保存10的幂,p[i]表示10的i次方,避免重复计算 p.push_back(1); for(int i=1;i<=9;i++){ p.push_back(p[i-1]*10); } for(int i=0;i<q;i++){ //遍历图书,找到读者需要的图书里编码最小的(先找到的第一个) int j=0; for(j=0;j<n;j++){ if(book[j]%p[len[i]]==code[i]){ cout<<book[j]<<endl; break; } } //如果遍历完都没有找到,输出-1 if(j==n){//注意这里为啥要这个判断,j为什么要声明在for外面? cout<<"-1"<<endl; } } } -
0
你好!我是你的OI教练。
这道题(NOIP 2017 普及组 T2)是一道非常典型的模拟/枚举题目。
数据范围 ,这意味着我们可以接受 的复杂度,也就是对于每一个读者,把所有书都检查一遍,计算机完全跑得过来。
下面是解题的几个关键突破口:
1. 核心逻辑:如何判断“以需求码结尾”?
题目给出了需求码的长度 和需求码 。 比如书的编码是
2123,需求码是23(长度 2)。 要判断2123的末尾是不是23,其实就是看2123除以 的余数是不是23。数学规律:
- 取最后 1 位:
number % 10 - 取最后 2 位:
number % 100 - 取最后 位:
number % (10的k次方)
所以,你只需要算出一个模数
mod = 10^len,然后判断book_id % mod == code即可。2. 策略:如何找到“最小”的?
题目要求输出最小的那个图书编码。这里有两种处理策略:
-
策略 A(推荐):先排序,再查找
- 在读入所有书的编码后,先用
sort把它们从小到大排序。 - 对于每个读者,从头到尾遍历排好序的书。
- 找到的第一个符合条件的书,一定就是最小的!直接输出并
break(停止当前读者的查找)。 - 如果遍历完了还没找到,就输出
-1。
- 在读入所有书的编码后,先用
-
策略 B:打擂台
- 不排序。对于每个读者,遍历所有书。
- 如果书符合条件,这就更新目前的“最小答案”(
ans = min(ans, book_id))。 - 初始答案设为一个无穷大或者 -1。
3. 小细节提示
- 10 的次幂:为了方便,你可以预处理一个数组
p[],p[1]=10, p[2]=100 ...,或者每次用循环算一下模数。尽量避免频繁使用pow函数(它是浮点运算,虽说这题也能过,但整数运算更稳)。 - 输入输出:注意 是读者的数量,外层循环是 次。
代码结构建议
1. 读入 n, q 2. 读入 n 本书的编码存入数组 a[] 3. sort(a + 1, a + n + 1) // 先排好序 4. 循环 q 次(处理每个读者): a. 读入 len, code b. 计算模数 mod = 10^len c. 遍历数组 a[]: 如果 (a[i] % mod == code): 输出 a[i],标记找到了,break d. 如果遍历完没找到,输出 -1思路很清晰了吧?快去试试写代码吧!
- 取最后 1 位:
-
0
C++ :
#include<bits/stdc++.h> using namespace std; struct book { int w; int num; }a[1000+1]; int i,j,k,l,n,m,b[1000+1]; int ask(int x,int a,int y) { int sz=a; int w=1; do { w*=10; sz--; }while(sz!=0); if((x%=w)==y)return 1; else return 0; } int main() { cin>>n>>m; for(i=1;i<=n;i++){ cin>>b[i]; } sort(b+1,b+n+1); for(i=1;i<=m;i++) { cin>>a[i].w>>a[i].num; } for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { k+=ask(b[j],a[i].w,a[i].num); if(ask(b[j],a[i].w,a[i].num)==1)break; } if(k==0)cout<<"-1"<<endl; else cout<<b[j]<<endl; k=0; } return 0; }
- 1
信息
- ID
- 3806
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者