中M2018秋C入门和进阶练习(进阶部分41——)

Posted jarvis0627

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了中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] = ; //输入数组终止符
            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
", 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("
");
        }
        sum = 0;
        m++;
    }
    if(count == 0) {
        printf("None");
    }
    return 0;
}

 

 
 
 








































以上是关于中M2018秋C入门和进阶练习(进阶部分41——)的主要内容,如果未能解决你的问题,请参考以下文章

一周入门MySQL—4数据库进阶练习

C语言进阶学习笔记二指针的进阶(练习篇)

C语言进阶笔记揭秘数据内部存储 !!

C语言进阶笔记揭秘数据内部存储 !!

C语言进阶笔记揭秘数据内部存储 !!

C语言进阶学习笔记二指针的进阶(重点必看+代码演示+练习)