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 <stdio.h>

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);
    else
        printf("%d-%d-%d-%d", a, b, c, sum % 11);
    return 0;
}

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

#include<stdio.h>
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<stdio.h>
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;j<i;j++)
        {
            if(k>data)
                break;
                sum+=i;
                k++;
        }
    }
    printf("%d",sum);
    return 0;
}

[NOIP2018]标题统计

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

 

正确的代码如下:

#include<stdio.h>
#include<string.h>
int main(){
    int sum=0,i;
    char s[100];
    gets(s);//gets才能吸收空格
    for(i=0;i<strlen(s);i++){
        if(s[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);
}

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

评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vex小摆子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值