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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章