1.
亲密数_1
2500年前数学大师毕达哥拉斯就发现,220与284两数之间存在着奇妙的联系:
220的真因数之和为:1+2+4+5+10+11+20+22+44+55+110=284
284的真因数之和为:1+2+4+71+142=220
毕达哥拉斯把这样的数对称为相亲数。
相亲数,也称为亲密数,如果整数A的全部因子(包括1,不包括A本身)之和等于B,且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。
从键盘任意输入两个整数m和n,编程判断m和n是否是亲密数。若是亲密数,则输出“Yes!”,否则输出“No!”
程序运行示例1
Input m, n:
220,284↙
Yes!
程序运行示例2Input m, n:
224,280↙
No!
输入格式: "%d,%d"
输出格式:
输入提示信息:"Input m, n:\n"
输出提示信息:"Yes!\n"
"No!\n"
#include<stdio.h> judgeclose(a,b); main() { printf("Input m, n:\n"); int m,n; scanf("%d,%d",&m,&n); if(judgeclose(m,n)==1) printf("Yes!\n"); else printf("No!\n"); } judgeclose(a,b) { int i,j,k=0; int s[20]={0},t[20]={0},e[20]={0},f[20]={0}; for(i=1;i<=a;i++) for(j=2;j<a;j++) { if (i*j==a) { s[k]=i; t[k]=j; k++; } } for(i=1;i<=b;i++) for(j=2;j<b;j++) { if (i*j==b) { e[k]=i,f[k]=j; k++; } } int s1=0,s2=0; for(i=0;i<20;i++) { s1+=s[i]+t[i]; s2+=e[i]+f[i]; } s1=s1/2+1; s2=s2/2+1; if(s1==b&&s2==a) return 1; else return 0; }
看我写的这串垃圾代码。。。
要是考试肯定半个小时构思+写肯定写不完。。。
再看看同一类型题大神的方法:
2.
(链接)一个数对(x,y)是亲和数对,当且仅当 x 的非自身的因数之和等于 y,且 y 的非自身的因数之和等于 x。如果(x,y)是亲和数对,那么认为(y,x)是与之相同的亲和数对。若 A<=x<=B,则称亲和数对(x,y)在[A,B]范围内。现输入范围 A 和 B,求 [A,B] 内所有亲和数对个数。例如 [200,1200] 内有两个亲和数对 (220,284) 和 (1184,1210),因为 220 的非自身因数和 1+2+4+5+10+11+20+22+44+55+110=284,284 的非自身因数之和为 1+2+4+71+142=220。
解一:解法骨架是枚举 [A,B] 范围内所有 x,算出 x 的非自身正因数之和 y(y < x),若 y 的非自身因数之和为 x,则代表找到了一个亲和数对。于是得到了一个直观的朴素解法。
解二:但显然上述解法效率过低。为了避免重复计算,我们创建一个 res[x] 数组保存 x 的因子和。于是得到了比解一快得多的解法。
解三:但是上述解法仍然太慢。问题在哪里?容易知道,时间主要耗费在了计算因子上(% 和 / 是同一个CPU指令,耗费时间相同)。我们不妨换一种思维方式,枚举因子 i,并把因子 i 加到 res[i*j] 里面,当枚举结束时,res[x] 就是 x 的因子和。这个方法快在两个方面:(1)机器算乘法本来就比除法快;(2)没有多余的整除判断。于是我们得到了最快的解法,并且代码比上面两种解法更为简洁。下面的代码利用了全局变量默认为空,没有 memset(res, 0, sizeof res)。
#include <stdio.h> int res[100000005]; int main() { int A, B, ans=0; scanf("%d%d", &A, &B); for(int i = 1; i <= B; ++i) for(int j = 2; i*j <= 2*B; ++j) res[i*j] += i; for(int x = A; x <= B; ++x) if(res[x] > x && res[res[x]] == x) ++ans; printf("%d\n", ans); return 0; }
需要说明的是
(要运行这个程序,我们需要在C99并添加新的头文件或C++编译器下进行!)
于是差距就出现了:手动滑稽hhh
Plus:C++真的比C语言简便好多啊
From:Kai
3.
完全数
完全数(Perfect Number),又称完美数或完数,它是指这样的一些特殊的自然数。它所有的真因子(即除了自身以外的约数)的和,恰好等于它本身,即m的所有小于m的不同因子(包括1)加起来恰好等于m本身。注意:1没有真因子,所以1不是完全数。计算机已经证实在10300以下,没有奇数的完全数。例如,因为6 = 1 + 2 + 3,所以6是一个完全数。
从键盘任意输入一个整数m,编程判断m是否是完全数。若m是完全数,则输出“Yes!”,并同时打印出每一个完美数的全部因子,以验证这个数确实是一个完美数。若m不是完全数,则输出“No!”
程序运行示例1
Input m:
28↙
Yes!
1,2,4,7,14
程序运行示例2
Input m:
6↙
Yes!
1,2,3
程序运行示例3
Input m:
1↙
No!
输入信息提示:"Input m:\n"
输入格式: "%d"
输出格式: "%d"
输出因子时用逗号间隔,格式为: ","
判断是完全数,输出信息提示:"Yes!\n"
判断不是完全数,输出信息提示: "No!\n"
//有了上一道题作为基础,这道题就显得很简单了//
#include<stdio.h> judgetrue(a); main() { printf("Input m:\n"); int m; scanf("%d",&m); judgetrue(m); } judgetrue(a) { int i,j,k=0; int s[20]={0},t[20]={0}; for(i=1;i<=a;i++) for(j=2;j<=a;j++) { if (i*j==a) { s[k]=i; t[k]=j; k++; } } int s1=0; for(i=0;i<20;i++) { s1+=s[i]; } if(s1==a) { printf("Yes!\n"); for(i=0;i<20;i++) { if(s[i]!=0) { printf("%d",s[i]); if(s[i+1]!=0) printf(","); } } } else printf("No!\n"); }
4.
五个水手在岛上发现一堆椰子,先由第1个水手把椰子分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。然后,第2个水手把剩下的4堆混合后重新分为等量的5堆,还剩下1个给了猴子,自己藏起1堆。以后第3、4个水手依次按此方法处理。最后,第5个水手把剩下的椰子分为等量的5堆后,同样剩下1个给了猴子。请用迭代法编程计算并输出原来这堆椰子至少有多少个。
**输出格式要求:"y = %d\n"
#include "stdio.h" int can(int k) { int i; for (i=1;i<=5;i++) { if ((k-1)%5!=0||k< 5) return 0; k=(k-1)/5*4; } return 1; } int main() { int ans=1; while (!can(ans)) ans++; printf("y = %d\n",ans); return 0; }
5.求1000内的
#include<stdio.h> #define m 1000 judgetrue(a); main() { int i; for(i=2;i<=m;i++) judgetrue(i); } judgetrue(a) { int i,j,k=0; int s[100]={0}; for(i=1;i<=a;i++) for(j=2;j<=a;j++) { if (i*j==a) { s[k]=i; k++; } } int s1=0; for(i=0;i<100;i++) { s1+=s[i]; } if(s1==a) { printf("\n%5d\n",s1); for(i=0;i<20;i++) { if(s[i]!=0) { printf("%5d",s[i]); } } } else; }
你可以发现:我每个程序都是在原程序的基础上进行修改而成的。
所以我把这些程序上传在了这个博客上,以备后事之需。
十一月 | ||||||
---|---|---|---|---|---|---|
日 | 一 | 二 | 三 | 四 | 五 | 六 |
27 | 28 | 29 | 30 | 31 | 1 | 2 |
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |