C语言初步-第39讲:问题求解——求素数(练习综合)
来源:互联网 发布:数据使用承诺书 编辑:程序博客网 时间:2024/06/03 21:58
任务和代码:
/**Copyright (c)2017 CSDN学院*All rights reserved*文件名称:main.c*作者: Osseyda完成日期:2017.9.27*版本号:v2.**问题描述:一个数如果恰好等于它的因子之和,这个数就称为“完数”。例如6=1+2+3,再如8的因子和是7(即1+2+4),8不是完数。 (1)输入一个数n,判断n是否是完数 (2)输出1000以内的所有完数*问题输出:输出1000以内的所有完数*/#include <stdio.h>int main(){ int i,m,total,is_complete,n=0; for(m=1;m<=1000;m++){ is_complete=1; total=0; for(i=1;i<m;i++){ if(m%i==0) total+=i; } if(m!=total){ is_complete=0; } if(is_complete==1){ printf("%d\t",m); n++; if(n%5==0) printf("\n"); } } return 0;}运行结果:
/*问题描述:亲密数:如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。求3000以内的全部亲密数。*问题输出:输出3000以内的全部亲密数。*/#include <stdio.h>int main(){ int m,i,j,a,b; for(m=1;m<=3000;m++){ a=0,b=0; for(i=1;i<m;i++){ if(m%i==0) a+=i; //a是m的因子和 } for(j=1;j<a;j++){ if(a%j==0) b+=j; //b是a的因子和 } if(b-m==0&&a!=m){ //若b=m,则a和m互为亲密数 printf("a=%d,其因子和为%d\t",m,a); printf("b=%d,其因子和为%d\t",a,m); printf("故a和b是一对亲密数\n"); } } return 0;}运行结果:
/*问题描述:求满足条件n=a!+b!+c!的所有三位数n,其中a,b,c分别为n的百、十、个位数。*问题输出:输出满足条件n=a!+b!+c!的所有三位数n.*/#include <stdio.h>int main(){ int n,a,b,c,i,fa,fb,fc; for(n=100;n<1000;n++){ c=n%10; b=(n/10)%10; a=n/100; fa=1,fb=1,fc=1; for(i=1;i<=a;i++) fa*=i; for(i=1;i<=b;i++) fb*=i; for(i=1;i<=c;i ++) fc*=i; if(n-fa-fb-fc==0) printf("%d\t",n); } return 0;}
如果不是三位数呢?(由求阿姆斯特朗数联想到另一种解法)
#include <stdio.h>int main(){ int n,m,k,i,fact,sfact; for(n=100;n<1000;n++){ k=n; sfact=0; while(k!=0){ m=k%10; k/=10; fact=1; for(i=1;i<=m;i++) fact*=i; sfact+=fact; } if(n==sfact) printf("%d\t",n); } return 0;}运行结果:
/*问题描述:输入一个正整数,输出它的反序数(反序数,即将其所有位的数字反过来。例如,123是321的反序数)*问题输出:输出1000000以内的正整数n,要求9n是n的反序数。*/#include <stdio.h>int main(){ long n,m,k; for(n=1;n<=1e6;n++){ //n的反序数是m k=n; m=0; while(k!=0){ m=m*10+k%10; //m进一位并加上余数 k/=10; } if(m==9*n) printf("%ld的反序数是%ld\t",n,m); } return 0;}运行结果:
/*问题描述:输入一个正整数,判断其是否为一个回文数(例1221、12321都是回文数,正着看、倒着看,是同一个数)。*问题输出:输出10000以内的所有回文数。*/#include <stdio.h>int main(){ int n,m,k,i=0; for(n=1;n<=1e4;n++){ //n的反序数是m k=n; m=0; while(k!=0){ m=m*10+k%10; //m进一位并加上余数 k/=10; } if(m==n){ //两个反序数相等就是回文数 printf("%d\t",n,m); i++; if(i%8==0) printf("\n"); } } return 0;}
运行结果:
/*问题描述:如果一个正整数等于其各个数字的立方和,则称该数为阿姆斯特朗数(亦称为自恋性数)。如 407=43+03+73就是一个阿姆斯特朗数*问题输出:输出1000以内的所有阿姆斯特朗数。*/#include <stdio.h>int main(){ int n,m,k,total; for(n=1;n<=1e3;n++){ k=n; total=0; while(k!=0){ m=k%10; k/=10; total+=m*m*m; } if(n==total) printf("%d\t",n); } return 0;}运行结果:
/*问题描述:很有趣的一个题目:2011年11月02日是一个回文日:2011 1102,在2011级同学做这道题时我们刚刚度过这一天!请列出本世纪有多少个回文日。*问题输出:输出本世纪所有的回文日。*/#include <stdio.h>int main(){ int year,month,day,fy,by,hm,hd,hfy,hby; for(year=2000;year<2100;year++){ fy=year/100,by=year%100; hfy=(fy%10)*10+(fy/10); hby=(by%10)*10+(by/10); for(month=1;month<=12;month++){ hm=(month%10)*10+(month/10); switch (month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: for(day=1;day<=31;day++){ hd=(day%10)*10+(day/10); if(hd==fy&&hm==by&&hby==month&&hfy==day) printf("%d %d %d\n",year,month,day); } break; case 4: case 6: case 9: case 11: for(day=1;day<=30;day++){ hd=(day%10)*10+(day/10); if(hd==fy&&hm==by&&hby==month&&hfy==day) printf("%d %d %d\n",year,month,day); } break; case 2: if(year%4==0&&year%100!=0||year%400==0){ for(day=1;day<=29;day++){ hd=(day%10)*10+(day/10); if(hd==fy&&hm==by&&hby==month&&hfy==day) printf("%d %d %d\n",year,month,day); } } else for(day=1;day<=28;day++){ hd=(day%10)*10+(day/10); if(hd==fy&&hm==by&&hby==month&&hfy==day) printf("%d %d %d\n",year,month,day); } } } } return 0;}
经过观察,如果年份的反序数就是月日的话,则ymd就是一个回文日,故另一种解法如下:
#include <stdio.h>int main(){ int year,month,day,hy,k; for(year=2000;year<2100;year++){ k=year; hy=0; while(k!=0){ hy=hy*10+k%10; k/=10; } for(month=1;month<=12;month++){ switch (month){ case 1: case 3: case 5: case 7: case 8: case 10: case 12: for(day=1;day<=31;day++){ if(hy==month*100+day) printf("%d %d %d\n",year,month,day); } break; case 4: case 6: case 9: case 11: for(day=1;day<=30;day++){ if(hy==month*100+day) printf("%d %d %d\n",year,month,day); } break; case 2: if(year%4==0&&year%100!=0||year%400==0){ for(day=1;day<=29;day++){ if(hy==month*100+day) printf("%d %d %d\n",year,month,day); } } else for(day=1;day<=28;day++){ if(hy==month*100+day) printf("%d %d %d\n",year,month,day); } } } } return 0;}
运行结果:
知识点总结:
1.求完数(即找出一个数除它本身外的所有因数)
取余
2.亲密数(本质上也是求因子和)
取余
3.分离出百、十、个位数 (利用求阿姆斯特朗数的方法联想到另一种更普遍的解法)
- c=n%10;
- b=(n/10)%10;
- a=n/100;
4.反序数(使末位数向左移一位并加上余数)
- k=n;
- m=0;
- while(k!=0){
- m=m*10+k%10; //m进一位并加上余数
- k/=10;
- }
5.回文数(一个数的反序数等于它本身)
6.阿姆数斯特朗数(分离出每一位数)
- while(k!=0){
- m=k%10;
- k/=10;
- }
7.回文日(根据反序数的原理,并将年月日分成四部分,判断倒序后的日期是否与原日期一致)
经过观察,如果年份的反序数就是月日的话,则ymd就是一个回文日,经分析,逻辑正确。不仅代码少了,从逻辑上,还减少了一半的运行量。
心得:
随着学习的深化,一个新的解题思路,或者使程序结构更清晰,都能对现有程序进行改进。
比如,在求回文日的时候, 我是利用 年份的反序数?=月份×100+日子,而贺利坚老师利用 月份?=年份后两位的反余数&&日子?=年份后两位的反余数,并把month,day提前表示出来,而不是放在判断表达式中,避免一个个试数,多次循环,利用is_cycle的判断表达式进行结果的输出,更具模块化。
阅读全文
1 0
- C语言初步-第39讲:问题求解——求素数(练习综合)
- C语言初步-第39讲:问题求解——求素数(输出格式控制)
- 第四周《C语言及程序设计》实践项目39 问题求解——求素数
- C语言初步-第35讲: 问题求解方法——迭代(另类求和)
- C语言初步-第35讲: 问题求解方法——迭代(Bessel函数 )
- C语言进阶-第6讲:递归法问题求解(递归求数组的最大值)
- C语言及程序设计初步—第7讲
- 第39课 问题求解——求素数 【数字游戏 项目1-6】
- 第3周 C语言及程序设计初步例程-39 求素数算法
- 39节 问题求解——求素数 课后
- C语言及程序设计初步例程-39 求素数算法
- 第1周 C语言及程序设计初步 例程-7 问题求解方法——迭代
- 第八讲:c/c++综合练习——存储电话号码
- C语言——求素数和
- C语言及程序设计初步例程-35 问题求解方法——迭代
- C语言进阶-第6讲:递归法问题求解(易列写递归方程)
- C语言进阶-第6讲:递归法问题求解(两数的最大公约数)
- C语言进阶-第22~23讲:问题求解的一般过程&数据结构及算法概述
- Java 中的异常和处理详解
- Java中的字符串常量池
- SSL/TLS协议运行机制的概述学习笔记
- Java虚拟机(九)——多态性理解
- Datatables嵌入Boostrap使用笔记
- C语言初步-第39讲:问题求解——求素数(练习综合)
- 欢迎使用CSDN-markdown编辑器
- Unity 与 太虚(VOID)AR 开发问题之调试崩溃
- 关于C#中类方法的重写和覆盖
- 现代信息化项目管理中常见的失误有哪些
- 软件测试之jenkins+maven+SVN
- Phalcon路由模式快速配置
- 一个简单的Java web服务器实现
- rdd转换为Set或者Map