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;
}
你可以发现:我每个程序都是在原程序的基础上进行修改而成的。
所以我把这些程序上传在了这个博客上,以备后事之需。
| 六月 | ||||||
|---|---|---|---|---|---|---|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
| 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 | 1 | 2 | 3 | 4 |