PTA 习题4-4 习题4-5 习题4-7

习题4-4
题目要求:编写程序求a+aa+aaa++⋯+aa⋯a(n个a)之和。
代码如下:

#include<stdio.h>
#include<math.h>int main(void){int n,a,i,sum,tmp;sum=0;tmp=0;scanf("%d %d",&a,&n);for(i=1;i<=n;i++){tmp=tmp+pow(10,(i-1))*a;sum=sum+tmp;}printf("s = %d",sum);return 0;
}

**本题思路:**首先找到规律,每一项都是前一项的数加上a*10的i-1次幂。所以tmp是用来存储上一个数的。for循环中先找本次所加数是谁,之后再sum中加上即可。举例令a=6
“6+(60+6)+(600+60+6)+(6000+600+60+6)+…”如此往复。

习题4-5
题目要求:
将一笔零钱换成5分、2分和1分的硬币,要求每种硬币至少有一枚,有几种不同的换法?
代码如下:

#include<stdio.h>
#include<math.h>int main(void){int i,j,k,total,count=0,mon;//mon总钱数,mar差额。 scanf("%d",&mon);for(i=mon/5;i>0;i--) //i>0的手法规定i最小取1for(j=mon/2;j>0;j--)for(k=mon;k>0;k--){if(i*5+j*2+k==mon){printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n",i,j,k,i+k+j);count++;}} //printf("%d=fen5",fen5);fen5测试点printf("count = %d",count);return 0;
}

本题思路:
三层for循环将5分,2分,1分硬币所有可能的数量都罗列出来(不要怕麻烦电脑,它可以用硬解把所有无用功都做了,只保留需要的部分)。取总和等于金额的,之后计数,输出。

习题4-6
题目要求:水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。 本题要求编写程序,计算所有N位水仙花数。
代码如下:

#include<stdio.h>
int pow(int i,int k);int pow(int i,int k){int j;int tmp=1;for(j=1;j<=k;j++){tmp=tmp*i;}return tmp;
}
int main(void){int i,N,tmp,sum;scanf("%d",&N);for(i=pow(10,N-1);i<pow(10,N);i++){tmp=i;sum=0;while(tmp){sum=sum+pow(tmp%10,N);tmp=tmp/10;}if(sum==i)printf("%d\n",i);}return 0;
}

解题思路:
检查每个N位数,判断其是否为水仙花数,就要将每个数拆开,拆成个十百千位数。具体操作有些小方法需要注意。

需要注意的点有几处:

1、math库中所含的pow函数很麻烦,自己建立的pow函数要简单快捷得多。如果只用库中所含pow函数会超时。注意在自拟中,temp初值是1不是0,它要被连乘,所以是1.

2、main函数中,for循环要包括所有N位数。

3、关于提取每一位上的数值,有tmp%10的小技巧,取得余数就是个位十位上的数值。在while循环中以tmp/=10来控制移向下一位。

习题4-7
题目要求
本题要求两个给定正整数的最大公约数和最小公倍数。
代码如下:

#include<stdio.h>int main(void){int M,N,i,j,max,y=0,b;scanf("%d %d",&N,&M);if(N>M)  max=N;elsemax=M;for(i=1;i<=M&&i<=N;i++){if(M%i == 0 && N%i == 0){y=i;}}printf("%d ",y);for(j=max;j<=M*N;j++){if(j%M == 0 && j%N == 0){break ;}}printf("%d",j);return 0;
}

解题思路:
其中注意一点,在求最大公约数时,没有用到break,是因为循环从1开始累加的,如果有比目前公约数更大的公约数,则会替换掉目前的公约数。公倍数最大不过两数相乘,从最大数开始循环到乘积即可,遇到最小公倍数就break掉。

未解问题:如果公约数不用本方法,而是从大到小循环如:

	for(i=max;i<=1;i--){if(M%i==0&&N%i==0){公约数=i;break;}}

会出现错误,尚未的到解决。

PTA 习题4-4 习题4-5 习题4-7

习题4-4
题目要求:编写程序求a+aa+aaa++⋯+aa⋯a(n个a)之和。
代码如下:

#include<stdio.h>
#include<math.h>int main(void){int n,a,i,sum,tmp;sum=0;tmp=0;scanf("%d %d",&a,&n);for(i=1;i<=n;i++){tmp=tmp+pow(10,(i-1))*a;sum=sum+tmp;}printf("s = %d",sum);return 0;
}

**本题思路:**首先找到规律,每一项都是前一项的数加上a*10的i-1次幂。所以tmp是用来存储上一个数的。for循环中先找本次所加数是谁,之后再sum中加上即可。举例令a=6
“6+(60+6)+(600+60+6)+(6000+600+60+6)+…”如此往复。

习题4-5
题目要求:
将一笔零钱换成5分、2分和1分的硬币,要求每种硬币至少有一枚,有几种不同的换法?
代码如下:

#include<stdio.h>
#include<math.h>int main(void){int i,j,k,total,count=0,mon;//mon总钱数,mar差额。 scanf("%d",&mon);for(i=mon/5;i>0;i--) //i>0的手法规定i最小取1for(j=mon/2;j>0;j--)for(k=mon;k>0;k--){if(i*5+j*2+k==mon){printf("fen5:%d, fen2:%d, fen1:%d, total:%d\n",i,j,k,i+k+j);count++;}} //printf("%d=fen5",fen5);fen5测试点printf("count = %d",count);return 0;
}

本题思路:
三层for循环将5分,2分,1分硬币所有可能的数量都罗列出来(不要怕麻烦电脑,它可以用硬解把所有无用功都做了,只保留需要的部分)。取总和等于金额的,之后计数,输出。

习题4-6
题目要求:水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。 本题要求编写程序,计算所有N位水仙花数。
代码如下:

#include<stdio.h>
int pow(int i,int k);int pow(int i,int k){int j;int tmp=1;for(j=1;j<=k;j++){tmp=tmp*i;}return tmp;
}
int main(void){int i,N,tmp,sum;scanf("%d",&N);for(i=pow(10,N-1);i<pow(10,N);i++){tmp=i;sum=0;while(tmp){sum=sum+pow(tmp%10,N);tmp=tmp/10;}if(sum==i)printf("%d\n",i);}return 0;
}

解题思路:
检查每个N位数,判断其是否为水仙花数,就要将每个数拆开,拆成个十百千位数。具体操作有些小方法需要注意。

需要注意的点有几处:

1、math库中所含的pow函数很麻烦,自己建立的pow函数要简单快捷得多。如果只用库中所含pow函数会超时。注意在自拟中,temp初值是1不是0,它要被连乘,所以是1.

2、main函数中,for循环要包括所有N位数。

3、关于提取每一位上的数值,有tmp%10的小技巧,取得余数就是个位十位上的数值。在while循环中以tmp/=10来控制移向下一位。

习题4-7
题目要求
本题要求两个给定正整数的最大公约数和最小公倍数。
代码如下:

#include<stdio.h>int main(void){int M,N,i,j,max,y=0,b;scanf("%d %d",&N,&M);if(N>M)  max=N;elsemax=M;for(i=1;i<=M&&i<=N;i++){if(M%i == 0 && N%i == 0){y=i;}}printf("%d ",y);for(j=max;j<=M*N;j++){if(j%M == 0 && j%N == 0){break ;}}printf("%d",j);return 0;
}

解题思路:
其中注意一点,在求最大公约数时,没有用到break,是因为循环从1开始累加的,如果有比目前公约数更大的公约数,则会替换掉目前的公约数。公倍数最大不过两数相乘,从最大数开始循环到乘积即可,遇到最小公倍数就break掉。

未解问题:如果公约数不用本方法,而是从大到小循环如:

	for(i=max;i<=1;i--){if(M%i==0&&N%i==0){公约数=i;break;}}

会出现错误,尚未的到解决。