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最小取1
	  for(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;
	else
	  max=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;
		}
	}

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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值