【解题思路】


        ① 用数组 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.0分

1 人评分

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论