原题链接:临时记忆
【解题思路】
① 用数组 a[] 标记目前所有书的状态,便于查找,提高效率;
② 用数组 b[] 储存小A记住的书,循环处理完他需要依次记住的书。
【1】所有书的状态标记
① 实际上数组 b[] 已经储存了小A记住的书了,但每次面对新书的时候都需要用 for 循环查找一遍已经记住的书,效率很低。因此不如多开一个数组记录所有书的状态,初始化所有书本 a[i]=0 ,若书本 i 被小A记住了,则 a[i]=1 ,数组 a[] 开3000以上就可以了,因为题目中说明了输入的 ki<=3000。
scanf("%d",&b[i]); // 依次输入需要记住的书 if(a[b[i]]==0) // 若此本书没记住过,s加1,表示需要多看1次书 { s++; a[b[i]]=1; // 标记此书记住了 } else // 若此本书已经记住了,当压根没输入过这本书 { i--; n--; // n表示要输入的书的数量,若i减1了,n也要跟着减1 }
【2】处理遗忘掉的书
① 若 i<m 表示还可以继续记新的书,若 i>=m 表示需要开始遗忘书了,也就是每次遗忘 b[i-m] 这本:
if(i-m>=0) a[b[i-m]]=0; // 标记b[i-m]这本书被忘记了
【注意事项】
① 采用标记的方法时要注意数据的取值范围,若太大或者没有数据范围,则此方法不可行。
【参考代码】
#include<stdio.h> int main(void) { int a[3001]={0},b[10001],n,m,s=0; scanf("%d%d",&n,&m); for(int i=0;i<n;i++) { scanf("%d",&b[i]); // 依次输入n本需要记住的书 if(a[b[i]]==0) // 若没记住,则次数加1 { s++; a[b[i]]=1; // 标记记住的书 } else // 若记住了,则不处理 { i--; n--; } if(i-m>=0) // 标记遗忘的书 a[b[i-m]]=0; } printf("%d",s); return 0; }
0.0分
1 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复