2020年秋季PAT乙级题解(C语言)

感兴趣的小伙伴可以先看看我的这篇文章哦,打开看看,说不定能帮到你一些~~

金陵科技学院软件工程学院软件工程专业

7-1 多二了一点 (15 分)
若一个正整数有 2n 个数位,后 n 个数位组成的数恰好比前 n 个数位组成的数多 2,则称这个数字“多二了一点”。如 24、6668、233235 等都是多二了一点的数字。

给定任一正整数,请你判断它有没有多二了那么一点。

输入格式:
输入在第一行中给出一个正整数 N(≤10^1000)。

输出格式:
在一行中根据情况输出下列之一:

如果输入的整数没有偶数个数位,输出 Error: X digit(s),其中 X 是 N 的位数;
如果是偶数位的数字,并且是多二了一点,输出 Yes: X - Y = 2,其中 X 是后一半数位组成的数,Y 是前一半数位组成的数;
如果是偶数位的数字,但并不是多二了一点,输出 No: X - Y != 2,其中 X 是后一半数位组成的数,Y 是前一半数位组成的数。

输入样例 1:
233235

输出样例 1:
Yes: 235 - 233 = 2

输入样例 2:
5678912345

输出样例 2:
No: 12345 - 56789 != 2

输入样例 3:
2331235

输出样例 3:
Error: 7 digit(s)

AC代码:

#include <stdio.h>
#include <string.h>
int check(char s[]){
    int i, len = strlen(s);
    for(i = 0;i < len / 2 - 1;i++){
        if(s[i] != s[i + len/2]) return 0;
    }
    if(s[len - 1] - s[len / 2 - 1] == 2) return 1;
    return 0;
}
int main(){
    char s[10001];
    scanf("%s", s);
    int i, len = strlen(s);
    if(len % 2 != 0) printf("Error: %d digit(s)\n", len);
    else{
        if(check(s)){
            printf("Yes: %s - ", s + len / 2);
            for(i = 0;i < len / 2;i++) printf("%c", s[i]);
            printf(" = 2\n");
        }else{
            printf("No: %s - ", s + len / 2);
            for(i = 0;i < len / 2;i++) printf("%c", s[i]);
            printf(" != 2\n");
        }
    }
    return 0;
}

7-2 数字之王 (20 分)
给定两个正整数N1<N2。把从N1到N2的每个数的各位数的立方相乘,再将结果的各位数求和,得到一批新的数字,再对这批新的数字重复上述操作,直到所有数字都是 1 位数为止。这时哪个数字最多,哪个就是“数字之王”。

例如N1=1和N2=10时,第一轮操作后得到 { 1, 8, 9, 10, 8, 9, 10, 8, 18, 0 };第二轮操作后得到 { 1, 8, 18, 0, 8, 18, 0, 8, 8, 0 };第三轮操作后得到 { 1, 8, 8, 0, 8, 8, 0, 8, 8, 0 }。所以数字之王就是 8。

本题就请你对任意给定的N1<N2求出对应的数字之王。

输入格式:
输入在第一行中给出两个正整数0<N1<N2≤10^3,其间以空格分隔。

输出格式:
首先在一行中输出数字之王的出现次数,随后第二行输出数字之王。例如对输入 1 10 就应该在两行中先后输出 6 和 8。如果有并列的数字之王,则按递增序输出。数字间以 1 个空格分隔,行首尾不得有多余空格。

输入样例:
10 14

输出样例:
2
0 8

AC代码:

#include <stdio.h>
#include <math.h>
int cal(int n){
    if(n == 0) return 0;
    int res = 1, sum = 0;
    while(n != 0){
        res *= pow(n % 10, 3);
        n /= 10;
    }
    while(res != 0){
        sum += res % 10;
        res /= 10;
    }
    return sum;
}
int main(){
    int n1, n2, a[1000], i, flag = 0, cnt = 0, k = 0, b[10] = {0}, max = -1;
    scanf("%d %d", &n1, &n2);
    for(i = n1;i <= n2;i++){
        if(i < 10) k++;
        a[cnt++] = i;
    }
    while(k != cnt){
        k = 0;
        for(i = 0;i < cnt;i++){
            a[i] = cal(a[i]);
            if(a[i] < 10) k++;
        }
    }
    for(i = 0;i < cnt;i++) b[a[i]]++;
    for(i = 0;i < 10;i++) if(b[i] > max) max = b[i];
    printf("%d\n", max);
    for(i = 0;i < 10;i++){
        if(b[i] == max){
            if(flag == 0){
                printf("%d", i);
                flag = 1;
            }else printf(" %d", i);
        }
    }
    return 0;
}

7-3 如需挪车请致电 (20 分)
在这里插入图片描述
上图转自新浪微博。车主用一系列简单计算给出了自己的电话号码,即:
2/2=1、3+2=5、 根号9=3、 根号9=3、0%=0、叁=3、5−2=3、9/3=3、1×3=3、2^3=8、8/2=4,最后得到的电话号码就是 153 3033 3384。

本题就请你写个程序自动完成电话号码的转换,以帮助那些不会计算的人。

输入格式:
输入用 11 行依次给出 11 位数字的计算公式,每个公式占一行。这里仅考虑以下几种运算:加(+)、减(-)、乘(*)、除(/)、取余(%,注意这不是上图中的百分比)、开平方根号(sqrt)、指数(^)和文字(即 0 到 9 的全小写汉语拼音,如 ling 表示 0)。运算符与运算数之间无空格,运算数保证是不超过 1000 的非负整数。题目保证每个计算至多只有 1 个运算符,结果都是 1 位整数。

输出格式:
在一行中给出电话号码,数字间不要空格。

输入样例:
2/2
3+2
sqrt9
sqrt9
6%2
san
5-2
9/3
1*3
2^3
8/2

输出样例:
15330333384

AC代码:

#include <stdio.h>
#include <string.h>
#include <math.h>
int main(){
    int i, j, cnt, a, b, k = 0, flag = 0;
    char pinyin[10][5] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};
    char s[10], c, genhao[5], res[12];
    for(i = 0;i < 11;i++){
        cnt = 0;
        flag = 0;
        scanf("%s", s);
        for(j = 0;s[j];j++){
            if(s[j] >= '0' && s[j] <= '9'){
                if(flag == 0){
                    cnt++;
                    flag = 1;
                }
            }else flag = 0;
        }
        if(cnt == 2){
            sscanf(s, "%d%c%d", &a, &c, &b);
            switch(c){
                case '+': res[k++] = a + b + '0'; break;
                case '-': res[k++] = a - b + '0'; break;
                case '*': res[k++] = a * b + '0'; break;
                case '/': res[k++] = a / b + '0'; break;
                case '%': res[k++] = a % b + '0'; break;
                case '^': res[k++] = pow(a, b) + '0'; break;
            }
        }else if(cnt){
            if(s[0] == 's'){
                sscanf(s, "%4s%d", genhao, &a);
                res[k++] = sqrt(a) + '0';
            }else res[k++] = s[0];
        }else{
            for(j = 0;j < 10;j++){
                if(!strcmp(pinyin[j], s)){
                    res[k++] = j + '0';
                    break;
                }
            }
        }
    }
    printf("%s", res);
    return 0;
}

7-4 胖达与盆盆奶 (20 分)
在这里插入图片描述
大熊猫,俗称“胖达”,会排队吃盆盆奶。它们能和谐吃奶的前提,是它们认为盆盆奶的分配是“公平”的,即:更胖的胖达能吃到更多的奶,等胖的胖达得吃到一样多的奶。另一方面,因为它们是排好队的,所以每只胖达只能看到身边胖达的奶有多少,如果觉得不公平就会抢旁边小伙伴的奶吃。

已知一只胖达每次最少要吃 200 毫升的奶,当另一份盆盆奶多出至少 100 毫升的时候,它们才能感觉到是“更多”了,否则没感觉。

现在给定一排胖达的体重,请你帮饲养员计算一下,在保持给定队形的前提下,至少应该准备多少毫升的盆盆奶?

输入格式:
输入首先在第一行给出正整数 n(≤10^4),为胖达的个数。随后一行给出 n 个正整数,表示 n 只胖达的体重(公斤)。每个数值是不超过 200 的正整数,数字间以空格分隔。

输出格式:
在一行中输出至少应该准备多少毫升的盆盆奶。

输入样例:
10
180 160 100 150 145 142 138 138 138 140

输出样例:
3000

样例解释:
盆盆奶的分配量顺序为:
400 300 200 500 400 300 200 200 200 300

AC代码:

#include <stdio.h>
int main(){
    int n, i, flag = 1, sum = 0, max, a[10001], b[10001];
    scanf("%d", &n);
    for(i = 0;i < n;i++){
        a[i] = 200;
        scanf("%d", &b[i]);
    }
    while(flag){
        flag = 0;
        for(i = 0;i < n;i++){
            if(i != n && b[i] > b[i + 1] && a[i] - a[i + 1] < 100){
                a[i] = a[i + 1] + 100;
                flag = 1;
            }else if(i != n && b[i] == b[i + 1] && a[i] != a[i + 1]){
                max = a[i] > a[i + 1] ? a[i] : a[i + 1];
                a[i] = max;
                a[i + 1] = max;
                flag = 1;
            }
            if(i != 0 && b[i] > b[i - 1] && a[i] - a[i - 1] < 100){
                a[i] = a[i - 1] + 100;
                flag = 1;
            }else if(i != 0 && b[i] == b[i - 1] && a[i] != a[i - 1]){
                max = a[i] > a[i - 1] ? a[i] : a[i - 1];
                a[i] = max;
                a[i - 1] = max;
                flag = 1;
            }
        }
    }
    for(i = 0;i < n;i++) sum += a[i];
    printf("%d", sum);
    return 0;
}

7-5 买地攻略 (25 分)
数码城市有土地出售。待售的土地被划分成若干块,每一块标有一个价格。这里假设每块土地只有两块相邻的土地,除了开头和结尾的两块是只有一块邻居的。每位客户可以购买多块连续相邻的土地。

现给定这一系列土地的标价,请你编写程序,根据客户手头的现金量,告诉客户有多少种不同的购买方案。

输入格式:
输入首先在第一行给出两个正整数:N(≤10^ 4)为土地分割的块数(于是这些块从 1 到 N 顺次编号);M(≤10^9)为客户手中的现金量。
随后一行给出 N 个正整数,其中第 i 个数字就是第 i 块土地的标价。
题目保证所有土地的总价不超过 10^9。

输出格式:
在一行中输出客户有多少种不同的购买方案。请注意客户只能购买连续相邻的土地。

输入样例:
5 85
38 42 15 24 9

输出样例:
11

样例解释:
这 11 种不同的方案为:
38
42
15
24
9
38 42
42 15
42 15 24
15 24
15 24 9
24 9

吐槽一下:这个第五题居然是这五题里最简单的,用了不到三分钟就AC了。

AC代码:

#include <stdio.h>
int main(){
    int n, m, i, j, sum, cnt = 0, a[10000];
    scanf("%d %d", &n, &m);
    for(i = 0;i < n;i++) scanf("%d", &a[i]);
    for(i = 0;i < n;i++){
        sum = 0;
        for(j = i;j < n;j++){
            sum += a[j];
            if(sum <= m) cnt++;
            else break;
        }
    }
    printf("%d", cnt);
    return 0;
}
  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Spiderman_94

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

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

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

打赏作者

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

抵扣说明:

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

余额充值