23级新生第一次考核题解

A.金铲铲,启动!

题目:

今天小胖和他的好朋友阿伟再在玩金铲铲之战的双人模式。

金铲铲的游戏规则中,每个人都有若干金币,金币可以用来买棋子,双人模式可以互相传送棋子。

游戏中传送棋子的规则比较复杂,这里你可以简单假设为一名玩家购买或者金币的棋子(需要扣除相应的金币数),然后传送给另一名玩家,另一名玩家卖掉该棋子并获得相应的金币。

在游戏中每回合开始时都可以额外获得个金币的利息,为已持有的金币数除以并向下取整,最大为只能为

举个例子:假设小胖当前回合有个金币,则TA在下个回合开始时可以获得个金币的利息。若小胖当前回合拥有或者更多的金币,TA在下个回合开始时也只能获得个金币的利息。

现在给出小胖和阿伟当前回合的金币,请问二人在下个回合开始时利息之和最大为多少?

解题思路:

根据题目意思我们可以知道,两位玩家最多可以获得 枚金币,两个人的金币数量都是大于 的,那么就意味着当前回合两个人一共可以获得 枚金币,如果有一个人当前的金币数量小于 ,我们就要开始考虑该怎么让两个人获得的金币数量之和是最大的,这个时候我们只需要让 的人把他除以 的余数给到 身上就可以了,然后这个时候再进行运算就是正确答案了。

参考代码
#include <stdio.h>

int main() {
    int a, b;
    scanf("%d%d", &a, &b);
    if (a > b) { // 当a大的时候,就交换a和b的位置
        int t = a;
        a = b;
        b = t;
    }
    if (a > 50) {
        printf(10);
    }
    else {
        a += b % 10;
        int tmp = a / 10 + b / 10;
        if (tmp > 10) {
            printf(10);
        }
        else {
            printf("%d", tmp);
        }
    }
    return 0;
}

B.买西瓜

题目:

小胖和阿伟都比较肥,夏天的时候喜欢吃西瓜,于是他们决定去买一个西瓜。

经过一顿挑挑选选,最终在水果店挑中了一个千克的大西瓜。

因为就买了一个,所以他们想分着吃,但是他们都是偶数爱好者+强迫症结合体,所以他们必须把这个西瓜分成偶数重量的两半。

这两个人挑西瓜很累,不想再去计算是否可以按照这个要求分成两份。

你能判断出来吗?

解题思路:

实际上就是一个很简答的问题,按照题目的意思就是,将 千克的西瓜分成偶数的两份,如果能分出来,就是 YES ,不行就是 NO ,很明显这道题是存在特判的,那就是 ,因为他无论怎么分都只有 这一种分法,其他的就是偶数才能分,奇数不能分,就相当于是一个判奇偶的问题了。

参考代码
#include <stdio.h>

int main() {
    int w;
    scanf("%d", &w);
    if (w > 2 && (w % 2 != 1)) {
        printf("YES\n");
    }
    else {
        printf("NO\n");
    }
    return 0;
}

C.近似素数

题目:

小胖很讨厌素数,素数是指一个大于的自然数,除了和它自身以外,不能被其他自然数整除的数。

但是这天TA在某本数学书上发现了另外一种素数——近似素数,其定义如下:如果一个大于的自然数正好有两个不同的素数除数,那么它便被称为近似素数。

举个例子:数字就是近似素数,而这些就不是。

现在小胖充满了好奇,想知道介于之间(包含)有多少个近似素数,你能帮帮TA嘛?

解题思路:

这道题考察的没什么别的东西,就是考察你们会不会判断质数。我们要判断质数,首先要知道什么是质数,质数的定义是除了一和他本身以外没有可以被它整除的数就是质数,现在知道了质数的定义之后,接下来就只需要遍历一遍 就行了。

参考代码
#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    int ans = 0;
    for (int i = 1; i <= n; i ++ ) {
        int cnt = 0;
        for (int j = 1; j <= i; j ++ ) { // 这一个循环判断有哪些数会被i整除
            if (i % j == 0 && j > 1) { // 1不是质数
                int flag = 1; // 用来判断是不是质数的,是质数为1,不是质数为0
                for (int k = 2; k < j; k ++ ) {
                    if (j % k == 0) { // 说明不是是质数
                        flag = 0;
                        break; // 提前中止
                    }
                }
                if (flag == 1) {
                    cnt ++ ;
                }
            }
        }
        if (cnt == 2) ans ++ ;
    }
    printf("%d", ans);
    return 0;
}

D.智商检测题

题目:

小胖喜欢玩一些智商检测游戏,这天阿伟给TA拿来了张卡片,每张卡片由编号,编号为的卡片上有一个正整数

阿伟说这些卡片上的数字,要么只有一个奇数,要么只有一个偶数,今天的智商检测问题就是看小胖能不能找出那个独特的奇数或者偶数。

小胖觉得这很难,于是TA来寻求你的帮助,希望你能借助编程来找出这个独特的数字。

解题思路:

根据题目意思我们可以看出,这是一道和奇数偶数有关的题目,再根据样例我们可以看出,只需要找到唯一的一个奇数的下标和唯一的一个偶数的下标就行了。

参考代码
#include <stdio.h>
int d[110]; // 数组空间一般多开10个

int main() {
    int n;
    scanf("%d", &n);
    int even = 0, odd = 0; // even代表偶数,odd代表奇数
    for (int i = 1; i <= n; i ++ ) {
        scanf("%d", &d[i]);
        if (d[i] % 2 == 0) even ++ ;
        else odd ++ ;
    }
    int ans = 0;
    if (odd == 1) {
        for (int i = 1; i <= n; i ++ ) {
            if (d[i] % 2 == 1) {
                ans = i;
            }
        }
    }
    else {
        for (int i = 1; i <= n; i ++ ) {
            if (d[i] % 2 == 0) {
                ans = i;
            }
        }
    }
    printf("%d", ans);
    return 0;
}

E.国旗

题目:

小胖来到了国旅游,这个国家正在执行新的标准,标准规定了国旗的样式:

- 国旗应该以大小的网格进行涂色,每个格子只能有这十种颜色的一种。
- 国旗应该是「条纹」形式,每一个横排都必须是相同的颜色方格,而两个相邻的横排不能用同一种颜色。

小胖看到了国的国旗,TA想知道这面国旗是否符合新的标准。

解题思路:

这道题其实没什么好说的,就是判断竖直方向上是不是两个相邻之间相同,再判断水平方向上是不是两个相邻之间相同。可能对你们新生来说比较难的就是字符串还没有学到。不过这题也可以不用字符串读入,可以直接用int类型读入,但是这样就要用到 scanf 的一个用法了,限定读入的int位数。

scanf("%1d", &a) 这样就代表这a这个整型变量只能读入一位数,这个的应用场景就是这道题,同理 scanf("%2d", &a) 就代表只能读入两位数,这样的应用场景有读入时间的类型,像 10:03 这样的时间。

这里我两种方法都写出来,仅供参考。

参考代码1
#include <stdio.h>
char s[110][110];

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    getchar(); // scanf读字符会读换行,所以需要用getchar把换行读掉
    for (int i = 0; i < n; i ++ ) {
        for (int j = 0; j < m; j ++ ) {
            scanf("%c", &s[i][j]);
        }
        getchar(); // 这里同理
    }
    int flag = 1; // 1代表满足要求,0代表不满足要求
    for (int i = 0; i < n; i ++ ) {
        for (int j = 1; j < m; j ++ ) {
            if (s[i][j] != s[i][j - 1]) { // 水平方向不满足要求
                flag = 0;
            }
        }
    }
    for (int i = 1; i < n; i ++ ) {
        for (int j = 0; j < m; j ++ ) {
            if (s[i][j] == s[i - 1][j]) { // 竖直方向不满足要求
                flag = 0;
            }
        }
    }
    if (flag) {
        printf("YES\n");
    }
    else {
        printf("NO\n");
    }
    return 0;
}
参考代码2
#include <stdio.h>
int s[110][110];

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i ++ ) {
        for (int j = 0; j < m; j ++ ) {
            scanf("%1d", &s[i][j]);
        }
    }
    int flag = 1; // 1代表满足要求,0代表不满足要求
    for (int i = 0; i < n; i ++ ) {
        for (int j = 1; j < m; j ++ ) {
            if (s[i][j] != s[i][j - 1]) { // 水平方向不满足要求
                flag = 0;
            }
        }
    }
    for (int i = 1; i < n; i ++ ) {
        for (int j = 0; j < m; j ++ ) {
            if (s[i][j] == s[i - 1][j]) { // 竖直方向不满足要求
                flag = 0;
            }
        }
    }
    if (flag) {
        printf("YES\n");
    }
    else {
        printf("NO\n");
    }
    return 0;
}

F.优雅序列

题目:

小胖对于一个优雅序列的定义为:对于所有的,需要保证

现在,小胖给你一个个正整数的序列,以及一个正整数,你可以做若干次以下操作:

- 选择一个,使加上

小胖想知道最少通过几次操作,可以是的这个序列变成优雅序列。

解题思路:

实际上只需要按照顺序遍历即可,从 遍历到 ,如果当前数比前一个数大的时候,就需要加上 ,直到加到大于前一个数为止。那么具体需要加多少呢?假设 ,则有当前 需要加上至少 +

参考代码
#include <stdio.h>
int b[2010]; // 数组空间一般多开10个

int main() {
    int n, d;
    scanf("%d%d", &n, &d);
    for (int i = 1; i <= n; i ++ ) {
        scanf("%d", &b[i]);
    }
    int ans = 0;
    for (int i = 2; i <= n; i ++ ) {
        if (b[i - 1] >= b[i]) {
            int t = (b[i - 1] - b[i]) / d + 1;
            ans += t;
            b[i] += t * d;
        }
    }
    printf("%d", ans);
    return 0;
}

G.简单输出

题目:

这是一道最简单最基础的题目,相信我。

只要你输出这一串字符:「abc%defghijklm\n」。(没有引号和句号)

怎么样,够简单吧,相信你十秒钟就能解决它。

解题思路:

这只是一个简单的输出题,难点可能就是里面有些字符需要转义吧。这个就推荐你们百度一下吧,我也不知道怎么解释。

参考代码
#include <stdio.h>

int main() {
    printf("abc%%defghijklm\n");
    return 0;
}

H.掷骰子

题目:

小胖、阿伟和lqmm正在玩掷骰子,这个骰子是一个普通的六面正方体骰子,点数从点各有一个。

他们规定掷出点数最大的人会获胜,小胖掷出的点数为,而阿伟掷出的点数为

现在轮到lqmm了,但是TA并不着急,TA只想知道自己的获胜概率有多大。

小胖和阿伟都是Gentelman,所以如果lqmm掷出和他们之中某个人相同的点数,就会认为lqmm的点数比较大。

现在,请你计算lqmm获胜的概率。

解题思路:

看完题目之后其实发现这道题不难,难就难在如何将分数化成最简,实际上,最简分数的分母和分子的最大公约数是 ,最大公约数的定义是, 两个数都可以整除的最大整数,这个是有一个算法的,叫做欧几里得算法。

参考代码
#include <stdio.h>

int main() {
    int a, b;
    scanf("%d%d", &a, &b);
    int t;
    if (a > b) {
        t = 6 - a + 1;
    }
    else {
        t = 6 - b + 1;
    }
    int A = t, B = 6;
    while (B != 0) {
        int tmp = A;
        A = B;
        B = tmp % B;
    }
    printf("%d/%d", t / A, 6 / A);
    return 0;
}

I.翻译问题

题目:

小胖最近在研究一种很新的语言——月半文。

这种语言单词的发音和拼写恰好与英文完全相反,例如英文单词「code」应该被翻译为月半文单词「edoc」。

然而,这个翻译过程很容易出错,所以小胖想问问你能不能帮忙鉴定一下TA是否翻译正确。

解题思路:

这道题目只需要将字符串反过来判断就可以了。

参考代码
#include <stdio.h>
#include <string.h>
char s1[110], s2[110];

int main() {
    // 读字符串,也就是字符数组不需要加 &
    scanf("%s", s1);
    scanf("%s", s2);
    int n = strlen(s1);
    int flag = 1; // 0 代表不符合要求,1代表符合要求
    for (int i = 0; i < n; i ++ ) {
        if (s1[i] != s2[n - i - 1]) flag = 0;
    }
    if (flag) {
        printf("YES\n");
    }
    else {
        printf("NO\n");
    }
    return 0;
}

J.Hello World

题目:

这又是一个签到题目,主要是想看看你这一周有没有好好学C语言。

不过,如果这题是简单的输出「Hello World」那未免也太无趣了一点。

所以需要你输入一个整数,输出个「Hello」,后面带一个「 World」(注意空格哦~)。

解题思路:

就是输出 Hello 再输出一个 World

参考代码
#include <stdio.h>

int main() {
    int n;
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) {
        printf("Hello");
    }
    printf(" World");
    return 0;
}

K.升级咯

题目:

小胖正在玩盗版金铲铲游戏,TA拿到了「升级咯」海克斯。

拿到这个海克斯,代表如果想从级升级到级的话,需要耗费个金币。

小胖现在的等级是,TA想升级到等级,请问TA一共需要多少金币?

解题思路:

这道题目意思其实已经很明显,就是让你求 级升到 级需要多少金币,不过这道题需要注意的就是序列 表示的是当前一级升到后面一级所需要的费用。也就是说,序列 表示的是第一级升到第二级需要的金币,第二级升到第三级需要的金币一直到第 级升到第 级需要的费用。

参考代码
#include <stdio.h>
int d[110];

int main() {
    int n, a, b;
    scanf("%d", &n);
    for (int i = 1; i <= n - 1; i ++ ) {
        scanf("%d", &d[i]);
    }
    scanf("%d%d", &a, &b);
    int ans = 0;
    for (int i = a; i < b; i ++ ) {
        ans += d[i];
    }
    printf("%d", ans);
    return 0;
}