《程序设计基础2021》题目集1 题解二

目录

引言

7-1 圆球体积 (10 分)

7-2 小明的家庭合影 (10 分)

7-3 装酒 (10 分)

7-4 算菜价2 (10 分)

7-5 将秒数转换成时分秒 (10 分)

7-6 扩展水仙花数 (10 分)

法零

法一 循环改分支 

法二 暴力解题

7-7 拆数 (10 分)

篇尾


引言

强制转换用的有点多,不知道的,可以去了解一下

7-1 圆球体积 (10 分)

#include <stdio.h>
#define pi 3.1415926535897932384626
int main(){
	double r=0,v=0;
	scanf("%lf",&r);
	v=(4/3.0)*pi*r*r*r;
	printf("%.2lf",v);	
    return 0;
}

7-2 小明的家庭合影 (10 分)

#include<stdio.h>
int main(){
	int a=0,b=0,c=0;
	scanf("%d %d",&a,&b);
	printf("%d",b-a);
	return 0; 
} 

没想到吧,就是个减法乁( ˙ ω˙乁) 

7-3 装酒 (10 分)

#include <stdio.h>
int main(){
	double b=0,w=0,n=0;
	scanf("%lf %lf",&b,&w);
	n=w/b;
	if(n-(int)n!=0)n++;
	printf("%d",(int)n);
    return 0;
}

7-4 算菜价2 (10 分)

#include<stdio.h>
int main(){
	int n=0;
	scanf("%d",&n);
	double a[n][2],m=0,sum=0;
	for(int j=0;j<n;j++){
		for(int k=0;k<2;k++){
				scanf("%lf",&a[j][k]);
		}
	}
	for(int j=0;j<n;j++){
		m=a[j][0]*a[j][1];
		if((int)(m*100)%10>=5)m+=0.1;
		m=(int)(m*10)/10.0;
		sum+=m;
	}
	printf("%.1lf",(int)(sum*10)/10.0);
	return 0; 
} 

输出时保留精度是按四舍五入的 

7-5 将秒数转换成时分秒 (10 分)

#include<stdio.h>
int main(){
	int s=0,m=0,h=0;
	scanf("%d",&s);
	if(s>=60){m=s/60;s=s%60;}
	if(m>=60){h=m/60;m=m%60;}
	printf("%d:%d:%d\n",h,m,s);
	return 0; 
} 

7-6 扩展水仙花数 (10 分)

法零

#include<stdio.h>
#include<math.h>
int main(){
	int n=0,t=0;
	scanf("%d",&t);
	for(int j=0;j<t;j++){
		n=0;
		scanf("%d",&n);
		for(int i=pow(10,n-1);i<pow(10,n);i++){
			if(i==pow(i/1000000000,n)+pow(i/100000000%10,n)+pow(i/10000000%10,n)+pow(i/1000000%10,n)+pow(i/100000%10,n)+pow(i/10000%10,n)+pow(i/1000%10,n)+pow(i/100%10,n)+pow(i/10%10,n)+pow(i%10,n))printf("%d\n",i);
		}
	}
    return 0;
}

其实,这个题这样写,是过不了的,因为时间复杂度太高了

我看了一下题目要求,时间限制是800ms,而代码长度限制却有16KB。

我这题代码长度才1KB,我是喜欢代码越短越好, 但这样时间复杂度上就考虑的比较少。

这道题,我还有两个大胆的想法,因为n是限制了范围的,顶多就3、4、5、6、7。

法一 循环改分支 

 顾名思义,就是把嵌套的那个循环改成分支,if还是switch随便你,反正n只有五个数。

#include<stdio.h>
#include<math.h>
int main(){
	int n=0,t=0;
	scanf("%d",&t);
	for(int j=0;j<t;j++){
		n=0;
		scanf("%d",&n);
		switch(n){
			case 3:
				for(int i=100;i<1000;i++){
					if(i==pow(i/100%10,3)+pow(i/10%10,3)+pow(i%10,3))printf("%d\n",i);
				}
				break;
			case 4:
				for(int i=1000;i<10000;i++){
					if(i==pow(i/1000%10,4)+pow(i/100%10,4)+pow(i/10%10,4)+pow(i%10,4))printf("%d\n",i);				
				}
				break;
			case 5:
				for(int i=10000;i<100000;i++){
					if(i==pow(i/10000%10,5)+pow(i/1000%10,5)+pow(i/100%10,5)+pow(i/10%10,5)+pow(i%10,5))printf("%d\n",i);
				}
				break;
			case 6:
				for(int i=100000;i<1000000;i++){
					if(i==pow(i/100000%10,6)+pow(i/10000%10,6)+pow(i/1000%10,6)+pow(i/100%10,6)+pow(i/10%10,7)+pow(i%10,7))printf("%d\n",i);
				
				}
				break;
			case 7:
				for(int i=1000000;i<10000000;i++){
					if(i==pow(i/1000000000,7)+pow(i/100000000%10,7)+pow(i/10000000%10,7)+pow(i/1000000%10,7)+pow(i/100000%10,7)+pow(i/10000%10,7)+pow(i/1000%10,7)+pow(i/100%10,7)+pow(i/10%10,7)+pow(i%10,7))printf("%d\n",i);
				}
				break;
		}
	}

    return 0;
}

有的时候就是这样,要勇于尝试,试了之后才知道 法一 还是不行。(ಥ_ಥ)

可能是求水仙花数的思维太复杂了,我觉得还是直接暴力解题吧,时间限制真令人头疼。

法二 暴力解题

我们现在知道,反正n只有五个数,所以也就只有种情况,

那么,我们就再大胆点,为什么不直接用 法零 直接算出五种情况对应的水仙花数,

(运行过 法零 代码应该都知道其是水仙花数并不多,每种情况也就四五个)

然后直接放到 法二 的分支里,简单粗暴的解决问题。

#include<stdio.h>
#include<math.h>
int main(){
	long int n=0,t=0;
	scanf("%ld",&t);
	for(int j=0;j<t;j++){
		n=0;
		scanf("%ld",&n);
		switch(n){
			case 3:
				printf("153\n370\n371\n407\n"); 
				break;
			case 4:
				printf("1634\n8208\n9474\n"); 
				break;
			case 5:
				printf("54748\n92727\n93084\n"); 
				break;
			case 6:
				printf("548834\n"); 
				break;
			case 7:
				printf("1741725\n4210818\n9800817\n9926315\n"); 
				break;
		}
	}
    return 0;
}

但是,这种暴力解题的方法我是不推荐的,它的使用条件极为苛刻。 

还有,考试是笔试,有本事也暴力解题, 我在评论区等你好消息,∠( ᐛ 」∠)_

7-7 拆数 (10 分)

#include <stdio.h>
int main(){
	int n=0;
    scanf("%d",&n);
    printf("%d %d",(n/100)+(n/10%10)+(n%10),(n/100)*(n/10%10)*(n%10));
    return 0;
}

篇尾

熬夜赶的,就这样。本来想昨晚发布的,但是PTA昨晚出问题了。

额,如果看不懂就看不懂吧,懒得注释了。

如果编辑器有用Dve-C++可以参考一下下面的语法改法,'l'和1在编辑器里太像了,可以看看 算菜价2 第17行。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值