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

7-1 祖传好运 (15 分)
我们首先定义 0 到 9 都是好运数,然后从某个好运数开始,持续在其右边添加数字,形成新的数字。我们称一个大于 9 的数字 N 具有祖传好运,如果它是由某个好运数添加了一个个位数字得到的,并且它能被自己的位数整除。

例如 123 就是一个祖传好运数。首先因为 1 是一个好运数的老祖宗,添加了 2 以后,形成的 12 能被其位数 2 (即 12 是一个 2 位数)整除,所以 12 是一个祖传好运数;在 12 后面添加了 3 以后,形成的 123 能被其位数 3 整除,所以 123 是一个祖传好运数。

本题就请你判断一个给定的正整数 N 是不是具有祖传的好运。

输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出正整数 K (≤1000);第 2 行给出 K 个不超过 10^9的待评测的正整数,注意这些数字都保证没有多余的前导零。

输出格式:
对每个待评测的数字,在一行中输出 Yes 如果它是一个祖传好运数,如果不是则输出 No。

输入样例:
5
123 7 43 2333 56160

输出样例
Yes
Yes
No
No
Yes

AC代码:

#include <stdio.h>
int main(){
    int k, a, t, i, j, cnt, flag;
    scanf("%d ", &k);
    for(i = 0;i < k;i++){
        scanf("%d ", &a);
        t = a;
        cnt = 0;
        flag = 0;
        while(t != 0){
            t /= 10;
            cnt++;
        }
        for(j = cnt;j > 0;j--){
            if(a % j == 0) a /= 10;
            else{
                flag = 1;
                break;
            }
        }
        if(!flag) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}

7-2 找奇葩 (20 分)
在一个长度为 n 的正整数序列中,所有的奇数都出现了偶数次,只有一个奇葩奇数出现了奇数次。你的任务就是找出这个奇葩。

输入格式:
输入首先在第一行给出一个正整数 n(≤10^4),随后一行给出 n 个满足题面描述的正整数。每个数值不超过 10 ^5,数字间以空格分隔。

输出格式:
在一行中输出那个奇葩数。题目保证这个奇葩是存在的。

输入样例:
12
23 16 87 233 87 16 87 233 23 87 233 16

输出样例:
233

AC代码:

#include <stdio.h>
int main(){
    int n, i, a[10000], b[100000] = {0};
    scanf("%d", &n);
    for(i = 0;i < n;i++){
        scanf("%d ", &a[i]);
        if(a[i] % 2 != 0) b[a[i]]++;
    }
    for(i = 0;i < n;i++){
        if(b[a[i]] % 2 != 0){
            printf("%d", a[i]);
            break;
        }
    }
    return 0;
}

7-3 舍入 (20 分)
不同的编译器对浮点数的精度有不同的处理方法。常见的一种是“四舍五入”,即考察指定有效位的后一位数字,如果不小于 5,就令有效位最后一位进位,然后舍去后面的尾数;如果小于 5 就直接舍去尾数。另一种叫“截断”,即不管有效位后面是什么数字,一概直接舍去。还有一种是“四舍六入五成双”,即当有效位的后一位数字是 5 时,有 3 种情况要考虑:如果 5 后面还有其它非 0 尾数,则进位;如果没有,则当有效位最后一位是单数时进位,双数时舍去,即保持最后一位是双数。

本题就请你写程序按照要求处理给定浮点数的舍入问题。

输入格式:
输入第一行给出两个不超过 100 的正整数 N 和 D,分别是待处理数字的个数和要求保留的小数点后的有效位数。随后 N 行,每行给出一个待处理数字的信息,格式如下:
指令符 数字
其中指令符是表示舍入方法的一位数字,1 表示“四舍五入”,2 表示“截断”,3 表示“四舍六入五成双”;数字是一个总长度不超过 200 位的浮点数,且不以小数点开头或结尾,即 0.123 不会写成 .123,123 也不会写成 123.。此外,输入保证没有不必要的正负号(例如 -0.0 或 +1)。

输出格式:
对每个待处理数字,在一行中输出根据指令符处理后的结果数字。

输入样例:
7 3
1 3.1415926
2 3.1415926
3 3.1415926
3 3.14150
3 3.14250
3 3.14251
1 3.14

输出样例:
3.142
3.141
3.142
3.142
3.142
3.143
3.140

AC代码:
本题测试点太坑了,写了很长时间,交了第一发拿到了18分,然后愣是到最后也没把最后两个测试点改对。这题的代码我先不贴出来,后面如果抽空把它改对了再贴出来。先把18分的截图贴这儿,希望后面能写出来并涨个教训。

2020年冬季PAT乙级题解(C语言)
7-4 最近的斐波那契数 (20 分)
斐波那契数列 Fn 的定义为:对 n≥0 有 Fn+2=Fn+1 + Fn,初始值为 F0=0 和 F1 =1。所谓与给定的整数 N 最近的斐波那契数是指与 N 的差之绝对值最小的斐波那契数。

本题就请你为任意给定的整数 N 找出与之最近的斐波那契数。

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

输出格式:
在一行输出与 N 最近的斐波那契数。如果解不唯一,输出最小的那个数。

输入样例:
305

输出样例:
233

样例解释
部分斐波那契数列为 { 0, 1, 1, 2, 3, 5, 8, 12, 21, 34, 55, 89, 144, 233, 377, 610, … }。可见 233 和 377 到 305 的距离都是最小值 72,则应输出较小的那个解。

AC代码:

#include <stdio.h>
int main(){
    int a = 0, b = 1, c = 1, n, former = a;
    scanf("%d", &n);
    while(c < n){
        former = c;
        a = b;
        b = c;
        c = a + b;
    }
    printf("%d", c - n >= n - former ? former : c);
    return 0;
}

7-5 子串与子列 (25 分)
子串是一个字符串中连续的一部分,而子列是字符串中保持字符顺序的一个子集,可以连续也可以不连续。例如给定字符串 atpaaabpabtt,pabt是一个子串,而 pat 就是一个子列。

现给定一个字符串 S 和一个子列 P,本题就请你找到 S 中包含 P 的最短子串。若解不唯一,则输出起点最靠左边的解。

输入格式:
输入在第一行中给出字符串 S,第二行给出 P。S 非空,由不超过 10^4个小写英文字母组成;P 保证是 S 的一个非空子列。

输出格式:
在一行中输出 S 中包含 P 的最短子串。若解不唯一,则输出起点最靠左边的解。

输入样例:
atpaaabpabttpcat
pat

输出样例:
pabt

AC代码:

#include <stdio.h>
#include <string.h>
int main(){
    char s[10001], p[10001];
    int i, j, t = 0, len, min = 10001, m, n, k = 0, flag = 0;
    scanf("%s\n%s", s, p);
	   while(1){
        for(i = 0;i < strlen(p);i++){
           if(!i){
               for(j = t + k;j < strlen(s);j++){
                   if(s[j] == p[i]){
                       k = 1;
                       break;
                   }
               }
               t = j;
           }else{
                for(j++;j < strlen(s);j++){
                    if(s[j] == p[i]) break;
                }
           }
           if(j == strlen(s)){ 
              flag = 1;
              break;
           }
        }
        if(flag == 1) break;
        len = j - t + 1;
        if(len < min){
            min = len;
            m = t;
            n = j;
        }
    }
    for(i = m;i <= n;i++) printf("%c", s[i]);
    return 0;
}
上一篇:基于QT5的libmodbus主从机实现


下一篇:ARM内核架构