7-41 计算阶乘和 (10 分)

对于给定的正整数N,需要你计算 S=1!+2!+3!+…+N!。

输入格式:
输入在一行中给出一个不超过10的正整数N。

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

输入样例:

3

输出样例:

9
#include <stdio.h>
int main()
{
	int n,i,sum=0,sum2=1;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		sum2=i*sum2;
		sum=sum+sum2;
	}
	printf("%d\n",sum);
	return 0;
 } 

7-42 整除光棍 (20 分)

这里所谓的“光棍”,并不是指单身汪啦~ 说的是全部由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(){
	int x,s=0,i=0,n;
	scanf("%d",&x);
	for(n=1;;n++){
		s=s*10+1;
		if(s>=x){
			i=1;
			printf("%d",s/x);
		}else if(i==1){
			printf("0");
		}
		s=s%x;
		if(s==0){
			break;
		}
	}
	printf(" %d",n);
	return 0;
}

7-43 Shuffling Machine (20 分)

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

题意:
模拟洗牌机,按照指定的顺序洗牌.
输入洗牌的次数,洗牌的顺序;
输出洗牌后的牌:S1-S13(1-13),H1-H13(14-26),C1-C13(27-39),D1-D13(40-52),J1、J2(53、54).

思路:
(1)开3个整型数组start[]、end[]、next[],存放洗牌前、洗牌后的牌和指定的洗牌顺序;再开一个字符数组map[]存放花色{‘S’,‘H’,‘C’,‘D’,‘J’};
(2)在一次洗牌的操作中,end[next[i]]=start[i]表示在指定的next[i]位置放入i位置的牌;
(3)map[(end[i]-1)/13]输出花色,(end[i]-1)%13+1输出花色后的数值;

#include <stdio.h>
int main()
{
	int n=54,i;
	int k,start[n],next[n],end[n];
	char map[5]={'S','H','C','D','J'};
	for(i = 1;i<=n;i++){
		start[i] = i;
	}
	scanf("%d",&k);	
	for(i = 1;i<=n;i++){
		scanf("%d",&next[i]);
	}	
	while(k--){
		for(i=1;i<=n;i++){
			end[next[i]]=start[i];
		}
		for(i=1;i<=n;i++){
			start[i]=end[i];//此时start[]需要变更
		}
	}
	for(i=1;i<=n;i++){
		printf("%c%d",map[(end[i]-1)/13],(end[i]-1)%13+1);
		if(i!=n)
			printf(" ");
	}
	printf("\n");
	return 0;
}

7-44 黑洞数 (20 分)

黑洞数也称为陷阱数,又称“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 main()
{
	int num,a,b,c,t,A,B,i=1;
	scanf("%d",&num);
	do{
	a=num%10;//个位 
	c=num/100;//百位
	b=(num%100)/10;//十位
	if(a<b) {
            t = a; a = b; b = t;
        }
        if(a<c) {
            t = a; a = c; c = t;
        }
        if(b<c) {
            t = b; b = c; c = t;
        } 
        A = a * 100 + b * 10 + c;/*从排后的最大数A与最小数B*/
        B = c * 100 + b * 10 + a;
        num = A - B;/*将最大数与最小数的差,重新赋给变量n,以便做循环判断或下次循环使用*/
        printf("%d: %d - %d = %d\n",i, A, B, num);
        i++;//序号
    } while(num!=495 && num!=0);
	return 0;
}

7-45 找完数 (20 分)

所谓完数就是该数恰好等于除自身外的因子之和。例如: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 a,b,sum=0,j=0,i,red=0;
	int sam[100]={0};
	scanf("%d %d",&a,&b);
	for(;a<=b;a++){
		sum=1;j=0;
		for(i=2;i<a/i;i++){//为了防止因数重复累计,所以i的取值随时更新,例如:21的因数3、7以防后面又加了7、3
			if(a%i==0){
				sam[++j]=i;//注意 ++j 和 j++ 的区别
				sam[++j]=a/i;
				sum=sum+i+a/i;
			}
		}
		if(sum==a){//符合条件时,开始输出
			if(red==1){
				printf("\n");
			}
			printf("%d = 1",a);
			for(i=0;i<=j;i++){
				if(i%2==1){
					printf(" + %d",sam[i]);
				}
			}
			for(;j>0;j--){
				if(j%2==0){
					printf(" + %d",sam[j]);
				}
			}
			red=1;
		}
	}
	if(!red){
		printf("None");
	}
	return 0;
}