NOIP练习题(1)

目录

NOIP:

[NOIP2008]ISBN号码

[NOIP2015]金币

[NOIP2018]标题统计


                                                     念念不忘,必有回响

最近小编不断的刷题,发现了有一类名称叫NOIP的题目,这类题目相比于常规的牛客网习题是难度更高的,因此小编对于NOIP这个东西抱有很强的好奇心,于是小编就去查了一下,结果大为震惊,原来有的人在高中初中就开始卷了。

 

NOIP:

全国青少年信息学奥林匹克联赛(National Olympiad in Informatics in Provinces,简称NOIP)自1995年至2020年已举办25次。每年由中国计算机学会统一组织。 NOIP在同一时间、不同地点以各省市为单位由特派员组织。全国统一大纲、统一试卷。初、高中或其他中等专业学校的学生可报名参加联赛。联赛分初赛和复赛两个阶段。初赛考察通用和实用的计算机科学知识,以笔试形式进行。复赛为程序设计,须在计算机上调试完成。参加初赛者须达到一定分数线后才有资格参加复赛。联赛分普及组和提高组两个组别,难度不同,分别面向初中和高中阶段的学生。复赛可使用C、C++、Pascal语言,2022年后将不可使用Pascal、C语言,只能使用C++。

实在是太恐怖了,这些题目都有一定的难度,下面一一来讲解:

[NOIP2008]ISBN号码

 这一题,小编最开始想到的办法其实并不是数组,小编对于数字的敏感度很高,换句话说,小编的思维太数学了,小编想的是用模(%)10和除(/)10,不断的实现每一位的数字的乘,然后再一一相加得到最终结果,但是因为最终无法实现字符和sum匹配出正确的Right,后面久久无法解决,最后采取使用数组的方法,错误的代码如下:

#include int main()
{int a, b, c, d;scanf("%d-%d-%d-%d", &a, &b, &c, &d);int sum = a * 1;int i = 4;int j = 9;int ret = b;int temp = c;while (ret != 0){sum += (ret % 10) * i;i--;ret = ret / 10;}while (temp != 0){sum += (c % 10) * j;j--;temp = temp / 10;}if (sum % 11 == d)printf("Right");else if (sum % 11 == 10)printf("%d-%d-%d-X", a, b, c);elseprintf("%d-%d-%d-%d", a, b, c, sum % 11);return 0;
}

但是数组的方法就不会有这样的麻烦,数组通过将13个字符排到数组中,将字符‘-’排除在外然后一一乘对于的数字,唯一值得注意的点就是根据ASCII码表,字符数字变成数字需要减去一个字符‘0’。正确的代码如下:

#include
int main()
{char arr[13];int i, j;scanf("%s",arr);int s = 0;for(i=0, j=1; i<11; i++){if(arr[i] != '-'){s += (arr[i]-'0')*j;j++;}}int m = s % 11;if(m == arr[12]-'0' || (m == 10 && arr[12] == 'X')){printf("Right\n");}else{if(m == 10){for(i=0; i<12; i++){printf("%c", arr[i]);}printf("X");}else{for(i=0; i<12; i++){printf("%c", arr[i]);}printf("%d", m);}}
}

[NOIP2015]金币

对于这样一个题目,很多小伙伴一看题目,就晕了头,这获得钱的数量和获得固定钱的天数都不固定,这应该如何是好?但是大家仔细想想,小编带着大家分析一下,我们首先创建一个发工资的天数,然后再这个天数里,无论或多或少,国王每天是不是都要给骑士发工资,并且发工资的天数都等于所发工资的值,那我们创建一个循环,其进入循环的条件是当前天数小于发工资,但是我们每天发的工资都不一样,因此我们需要创建第二循环,第一个循环创建一个变量,并初始化为1,作为第二个循环的条件,第二个循环就是应该发这个工资的天数,第二个变量就初始化为0,并条件是小于第一个变量,这样我们的两个循环就建好了,后面只用当当前天数大于发工资的天数的时候,这个时候退出循环,使用一个if语句,然后将每一天的工资相加就是我们所需要的值,正确代码如下:

#include
int main()
{int data = 0;//预计天数int sum = 0;int k = 1;//当前天数scanf("%d",&data);for(int i = 1;k<=data;i++){for(int j = 0;jdata)break;sum+=i;k++;}}printf("%d",sum);return 0;
}

[NOIP2018]标题统计

这个题目相比前两个题目而言,是简单一点的,并不需要我们过多的思考,只需要将字符串看成一个字符型数组,其中需要使用gets()函数来吸收空格,不然可能导致程序误判。

 

正确的代码如下:

#include
#include
int main(){int sum=0,i;char s[100];gets(s);//gets才能吸收空格for(i=0;i='0'&&s[i]<='9'){sum++;}if(s[i]>='a'&&s[i]<='z'){sum++;}if(s[i]>='A'&&s[i]<='Z'){sum++;}}printf("%d",sum);
}

大家可以看到对于高中生,初中生可能有一点困难,但是对于我们大学生来说,刚刚好,小编发现这种题目可以极大程度的开发我们编程潜力,不逼自己一把,都不知道自己可以那么那么的厉害,小编后续还会带来这一期的更新,如果小伙伴们看的满意,给小编一个赞吧!


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部