1. 程式人生 > >中M2018秋C入門和進階練習(進階部分41——)

中M2018秋C入門和進階練習(進階部分41——)

  • 7-41 計算階乘和 (10 分)(PTA)

對於給定的正整數N,需要你計算 S=1!+2!+3!+...+N!。

輸入格式:
輸入在一行中給出一個不超過10的正整數N。

輸出格式:
在一行中輸出S的值。

輸入樣例:
3
輸出樣例:
9

// 計算階乘和

#include<stdio.h>
int factorial(int num){
    if (num==1) return 1;
    else return num*factorial(num-1);
}
int main(){
    int N, sum=0;
    scanf("%d
", &N); for (int i=1;i<=N;i++){ sum += factorial(i); } printf("%d", sum); return 0; }
  • 7-42 整除光棍 (20 分)(PTA)

這裡所謂的"光棍",並不是指單身汪啦~ 說的是全部由1組成的數字,比如1、11、111、1111等。傳說任何一個光棍都能被一個不以5結尾的奇數整除。比如,111111就可以被13整除。 現在,你的程式要讀入一個整數x,這個整數一定是奇數並且不以5結尾。然後,經過計算,輸出兩個數字:第一個數字s,表示x乘以s是一個光棍,第二個數字n是這個光棍的位數。這樣的解當然不是唯一的,題目要求你輸出最小的解。

提示:一個顯然的辦法是逐漸增加光棍的位數,直到可以整除x為止。但難點在於,s可能是個非常大的數 —— 比如,程式輸入31,那麼就輸出3584229390681和15,因為31乘以3584229390681的結果是111111111111111,一共15個1。

輸入格式:
輸入在一行中給出一個不以5結尾的正奇數x(<1000)。

輸出格式:
在一行中輸出相應的最小的s和n,其間以1個空格分隔。

輸入樣例:
31
輸出樣例:
3584229390681 15

// 整除光棍

#include <stdio.h>
int main() {
    char a[1000]; //建立存表
    int
len = 0, count = 0; int n; int t = 1; scanf("%d", &n); while(1) { count++; if(len || t/n)//商第一位為0,不存入陣列中 { a[len] = '0'+t/n; //把數字變為字元儲存 len++; } t %= n; //取餘數 if(t == 0)//判斷餘數是否為零,餘數為0結束 { a[len] = '\0'; //輸入陣列終止符 printf("%s %d", a, count); break; } t = t*10+1; } return 0; }
  •  7-43 Shuffling Machine (20 分)(PTA)

Shuffling is a procedure used to randomize a deck of playing cards. Because standard shuffling techniques are seen as weak, and in order to avoid "inside jobs" where employees collaborate with gamblers by performing inadequate shuffles, many casinos employ automatic shuffling machines. Your task is to simulate a shuffling machine.

The machine shuffles a deck of 54 cards according to a given random order and repeats for a given number of times. It is assumed that the initial status of a card deck is in the following order:

S1, S2, ..., S13,
H1, H2, ..., H13,
C1, C2, ..., C13,
D1, D2, ..., D13,
J1, J2
where "S" stands for "Spade", "H" for "Heart", "C" for "Club", "D" for "Diamond", and "J" for "Joker". A given order is a permutation of distinct integers in [1, 54]. If the number at the i-th position is j, it means to move the card from position i to position j. For example, suppose we only have 5 cards: S3, H5, C1, D13 and J2. Given a shuffling order {4, 2, 5, 3, 1}, the result will be: J2, H5, D13, S3, C1. If we are to repeat the shuffling again, the result will be: C1, H5, S3, J2, D13.

Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer K (≤20) which is the number of repeat times. Then the next line contains the given order. All the numbers in a line are separated by a space.

Output Specification:
For each test case, print the shuffling results in one line. All the cards are separated by a space, and there must be no extra space at the end of the line.

Sample Input:
2
36 52 37 38 3 39 40 53 54 41 11 12 13 42 43 44 2 4 23 24 25 26 27 6 7 8 48 49 50 51 9 10 14 15 16 5 17 18 19 1 20 21 22 28 29 30 31 32 33 34 35 45 46 47
Sample Output:
S7 C11 C10 C12 S1 H7 H8 H9 D8 D9 S11 S12 S13 D10 D11 D12 S3 S4 S6 S10 H1 H2 C13 D2 D3 D4 H6 H3 D13 J1 J2 C1 C2 C3 C4 D1 S5 H5 H11 H12 C6 C7 C8 C9 S2 S8 S9 H10 D5 D6 D7 H4 H13 C5

// Shuffling Machine

#include<stdio.h>
int main() {
    int n, cnt = 0;
    int *p;
    int set[54], start[54], end[54];
    scanf("%d", &n);

    for (int i = 0; i < 54; i++) {
        scanf("%d", &set[i]);
        start[i] = i;
    }

    int flag = 1;
    while(n) {
        if (flag) {
            for (int i = 0; i < 54; i++) {
                end[set[i]-1] = start[i];
            }
            flag = 0;
        }else {
            for (int i = 0; i < 54; i++) {
                start[set[i]-1] = end[i];
            }
            flag = 1;
        }
        n--;
    }

    if (flag) p = start;
    else p = end;

    while(1) {
        if(*p >= 0 && *p <= 12) {
            if (cnt != 53) printf("S%d ", *p+1);
            else printf("S%d", *p+1);
            p++;
        }else if(*p > 12 && *p <= 25) {
            if (cnt != 53) printf("H%d ", *p+1-13);
            else printf("H%d", *p+1-13);
            p++;
        }else if(*p > 25 && *p <= 38) {
            if (cnt != 53) printf("C%d ", *p+1-26);
            else printf("C%d", *p+1-26);
            p++;
        }else if(*p > 38 && *p <= 51) {
            if (cnt != 53) printf("D%d ", *p+1-39);
            else printf("D%d", *p+1-39);
            p++;
        }else if(*p > 51 && *p <= 53) {
            if (cnt != 53) printf("J%d ", *p+1-52);
            else printf("J%d", *p+1-52);
            p++;
        }
        if (cnt == 53) {
            break;
        }
        cnt++;
    }

    return 0;
}
  • 7-44 黑洞數 (20 分)(PTA)

黑洞數也稱為陷阱數,又稱"Kaprekar問題",是一類具有奇特轉換特性的數。

任何一個各位數字不全相同的三位數,經有限次"重排求差"操作,總會得到495。最後所得的495即為三位黑洞數。所謂"重排求差"操作即組成該數的數字重排後的最大數減去重排後的最小數。(6174為四位黑洞數。)

例如,對三位數207:

第1次重排求差得:720 - 27 = 693;
第2次重排求差得:963 - 369 = 594;
第3次重排求差得:954 - 459 = 495;
以後會停留在495這一黑洞數。如果三位數的3個數字全相同,一次轉換後即為0。

任意輸入一個三位數,程式設計給出重排求差的過程。

輸入格式:
輸入在一行中給出一個三位數。

輸出格式:
按照以下格式輸出重排求差的過程:

序號: 數字重排後的最大數 - 重排後的最小數 = 差值
序號從1開始,直到495出現在等號右邊為止。

輸入樣例:
123
輸出樣例:
1: 321 - 123 = 198
2: 981 - 189 = 792
3: 972 - 279 = 693
4: 963 - 369 = 594
5: 954 - 459 = 495

// 黑洞數

#include<stdio.h>
int kaprekar_min();
int kaprekar_max();
int kaprekar_min(int N) {
    int a, b, c, max, min, mid_num, max_num, min_num;
    a = N/100;
    b = (N-a*100)/10;
    c = N%10;
    max_num = ((a >= b ? a: b) >= c) ? (a >= b ? a: b): c;
    min_num = ((a <= b ? a: b) <= c) ? (a <= b ? a: b): c;
    mid_num = a + b + c - max_num - min_num;
    min = min_num*100 + mid_num*10 + max_num;
    return min;
}
int kaprekar_max(int N) {
    int a, b, c, max, min, mid_num, max_num, min_num;
    a = N/100;
    b = (N-a*100)/10;
    c = N%10;
    max_num = ((a >= b ? a: b) >= c) ? (a >= b ? a: b): c;
    min_num = ((a <= b ? a: b) <= c) ? (a <= b ? a: b): c;
    mid_num = a + b + c - max_num - min_num;
    max = max_num*100 + mid_num*10 + min_num;
    return max;
}
int main() {
    int N, max = 0, min = 0;
    scanf("%d", &N);
    max = kaprekar_max(N);
    min = kaprekar_min(N);
    for (int i = 1, temp = 0; i < 100; i++) {
        printf("%d: %d - %d = %d\n", i, max, min, max-min);
        if(max-min == 495) break;

        else {
            N = max-min;
            max = kaprekar_max(N);
            min = kaprekar_min(N);
        }
    }
    return 0;
}
  • 7-45 找完數 (20 分)(PTA)

所謂完數就是該數恰好等於除自身外的因子之和。例如:6=1+2+3,其中1、2、3為6的因子。本題要求編寫程式,找出任意兩正整數m和n之間的所有完數。

輸入格式:
輸入在一行中給出2個正整數m和n(1<m≤n≤10000),中間以空格分隔。

輸出格式:
逐行輸出給定範圍內每個完數的因子累加形式的分解式,每個完數佔一行,格式為"完數 = 因子1 + 因子2 + ... + 因子k",其中完數和因子均按遞增順序給出。若區間內沒有完數,則輸出"None"。

輸入樣例:
2 30
輸出樣例:
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14

// 找完數

#include <stdio.h>

int main() {
    int m, n;
    int i, sum = 0;
    int ret = 0;
    int count = 0;
    scanf("%d %d", &m, &n);
    while(m <= n) {
        for(i = 1; i < m; i++) {
            if(m%i == 0) {
                sum += i;
            }
        }
        if(sum == m) {
            count++;
            printf("%d = ", m);
            for(i = 1; i < m; i++) {
                if(m%i == 0) {
                    ret++;
                    int _sum = 0;
                    _sum += i;
                    while(ret > 1) {
                        printf(" + ");
                        if(_sum = m) {
                            break;
                        }
                    }
                    printf("%d", i);
                }
            }
            ret = 0;
            printf("\n");
        }
        sum = 0;
        m++;
    }
    if(count == 0) {
        printf("None");
    }
    return 0;
}