PAT乙级题解1001-1005

1001 害死人不偿命的(3n+1)猜想

将奇数情况转换为偶数,最后只对偶数做除二处理。

#include<stdio.h>

int main()
{
    int n, count = 0;
    scanf("%d",&n);
    while (n !=1 ){
        count++;
        if (n & 1) 
            n = 3 * n + 1;
        n /= 2;
    }
    printf("%d\n",count);
    return 0;
}

1002 写出这个数

需要取每一位,以字符串方式输入取每位转化为整数更方便。用汉语拼音输出和的每一位,即建立0~9每个数字与拼音的映射即可。注意“零”是后鼻音(原谅我前后鼻音不分)

#include<stdio.h>

int main()
{
    char c;
    int sum = 0;
    char s[15][5] = {"ling", "yi", "er", "san", "si", 
                     "wu", "liu", "qi", "ba", "jiu"};
                     
    while ((c = getchar()) != '\n') 
        sum += c - '0';
    if(sum / 100)                           
        printf("%s ", s[sum / 100]);
    if(sum / 10)                           
        printf("%s ", s[sum / 10 % 10]);
    printf("%s", s[sum % 10]);        
    return 0;
}

1003 我要通过!

建立一个状态机,根据条件进行状态间的转换。需要满足的要求如下:
要求一:

P 和 T只出现一次,且P与T中间的A的个数大于等于1

要求二:

三段A序列个数满足关系:左边A序列个数 X 中间A序列个数 = 右边A序列个数

关于要求二的分析:最开始正确的序列来自于 “2” 中 “xPATx”,所以 “3” 中的 “aPbTc” 中,‘a’ 和 ‘c’ 有相同数量的A,此时 ‘b’ 中只有一个A,满足此关系,之后的 “aPbATca” ,中间多一个A,右侧多了左边的A的数量,因为三为递归定义,同理,所有都满足此关系,类似数学归纳法思想,可得此等式。

#include<stdio.h>
#include<string.h>

#define MAX 105

int main() 
{
    int n;
    scanf("%d", &n);
    while (n-->0){
        char c, s[MAX];
        int size1 = 0, size2 = 0, size3 = 0;
        int status = 0;
        int i = 0, len;
        scanf("%s", s);
        len = strlen(s);
        while (i < len){
            c = s[i++];
            if (status == -1) break;
            if (c != 'P' && c != 'A' && c != 'T'){
                status = -1;
                continue;
            }
            if (status == 0){
                if (c == 'A')
                    size1++;
                else if (c == 'P') 
                    status = 1;
                else
                    status = -1;
            } else if (status == 1){
                if (c == 'A')
                    size2++;
                else if (size2 >= 1 && c == 'T')
                    status = 2;
                else
                    status = -1;
            } else if (status == 2){
                if (c == 'A')
                    size3++;
                else 
                    status = -1;
            }
        }    
        if (status == 2 && size3 == size2 * size1)
            printf("YES\n");
        else
            printf("NO\n");         
    }
    return 0;
}

1004 成绩排名

维护两个最值即可。

#include<stdio.h>
#include<string.h>

typedef struct{
    char name[15];
    char id[15];
    int score;
}Record;

void copy(Record *a, Record b)
{
    strcpy(a->name,b.name);
    strcpy(a->id, b.id);
    a->score = b.score;
}

int main() 
{   
    Record max, min, tmp;
    int n, sign = 1;
    scanf("%d", &n);
    while (n-->0) {
        scanf("%s%s%d", tmp.name, tmp.id, &(tmp.score));
        if (sign){
            copy(&max, tmp);
            copy(&min, tmp);
            sign = 0;
        }
        if (max.score < tmp.score)
            copy(&max, tmp);
        if (min.score > tmp.score) 
            copy(&min, tmp);
    }
    printf("%s %s\n", max.name, max.id);
    printf("%s %s\n", min.name, min.id);
    return 0;
}

1005 继续(3n+1)猜想

类似筛法求素数思想,筛玩剩下的从小到大输出即可。

#include<stdio.h>

#define MAX 10000
int num[MAX]={0};

int main()
{
    int k, n;
    scanf("%d", &k);
    while (k-->0) {
        scanf("%d", &n);
        num[n] = 1;
    }
    for (int i = 0; i < MAX; i++) {
        if (num[i] == 0) continue;
        int tmp;
        tmp = i;
        while (tmp != 1) {
            if (tmp&1) 
                tmp = tmp * 3 + 1;
            tmp /= 2;
            if (num[tmp] == 1)
                num[tmp] = 0;
        }
    }
    int sign = 1;
    for (int i = MAX - 1; i >= 0; i--) {
        if (num[i] == 1) {
            if (sign) {
                sign = 0;
                printf("%d", i);
            } else {
                printf(" %d", i);
            }
        }
    }
    printf("\n");
    return 0;
}

欢迎大家访问个人博客www.songhz.cn

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值