(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)
目录
第1关:求和
题目:
题目描述:给你一个n,要求你编写一个函数求1+2+.......+n.
输入一个n
输出1+2+.......+n的和
样例输入:
100
样例输出:
5050
代码思路:
这题只需要创建一个有for循环的函数,将n~1的数相加即可
代码表示:
#include<stdio.h> //编写函数 /*********Begin*********/ int a(int n) { int sum=0; for(int i =1;i<=n;i++) { sum += i; } return sum; } /*********End**********/ int main(void) { /*********Begin*********/ int n,sum; scanf("%d",&n); sum=a(n); printf("%d",sum); /*********End**********/ return 0; }
第2关:回文数计算
题目:
本关任务:编写函数求区间[200,3000]中所有的回文数,回文数是正读和反读都是一样的数。如525, 1551
输出区间[200,3000]中所有的回文数,一行一个回文数,不需要输出其它无关的字符。
202
212
222
232
242
.....
代码思路:
本题的难点在于回文数的判断,我的想法是通过%求出原数k的每一位,然后将其*10重新组合,重新组合后的数如果与前面的数相等,那就是回文数
代码表示:
#include<stdio.h> void solve() { /*********Begin*********/ int i, k, t; for (i = 200; i <= 3000; i++) { k = i, t = 0; while (k) { t *= 10; t += k % 10; k /= 10; } if (t == i) printf("%d\n", i); } /*********End**********/ } int main(void) { solve(); return 0; }
第3关: 编写函数求表达式的值
题目:
题目描述:有如下表达式 s = 1 + 1 / 3 + (1 * 2) / (3 * 5) + (1 * 2 * 3) / (3 * 5 * 7) + .... + (1 * 2 * 3 * .... * n) / (3 * 5 * 7 * ... * (2 * n + 1))。
编写函数求给出的n所对应的表达式s的值。
样例输入:
4
样例输出:
1.5492063492
代码思路:
这题的难点在于将不断变化的分子分母表示出来,我用的是循环的方法,分子用for循环每次加1,分母每次加2,然后将其累乘
代码表示:
#include<stdio.h> //编写题目要求的函数 /*********Begin*********/ double sum(int n) { double sum = 1, t1 = 1, t2 = 1, a = 1; int i; for (i = 1; i <= n; i++) { t1 *= i; t2 *= (a += 2); sum += t1 / t2; } } /*********End**********/ int main(void) { /*********Begin*********/ int n; scanf("%d", &n); printf("%.10f\n", sum(n)); /*********End**********/ return 0; }
第4关:阶乘数列:
题目:
题目描述:求Sn=1!+2!+3!+4!+5!+…+n!之值,其中n是一个数字。
样例输入:
5
样例输出:
153
提示:
用int可能会溢出,需要用能表示更大范围的long long int(注:VC6.0不支持此类型,VC下使用可使用__int64替代)
代码思路:
这题的难点在于如何表示阶乘,我这里采用for循环,先用1*1表示1的阶乘,然后第一次循环后就是1*2表示2的阶乘,第二次循环就是1*2的值*3表示3的阶乘.....每一次循环都有sum += t使每一次的阶乘可以相加
代码表示:
#include<stdio.h> long long sum(int n) { long long sum = 0, t = 1; int i; for (i = 1; i <= n; i++) { t *= i; sum += t; } return sum; } /*********End**********/ int main(void) { /*********Begin*********/ int n; scanf("%d", &n); printf("%lld\n", sum(n)); /*********End**********/ return 0; }
第5关:亲密数:
题目:
题目描述:两个不同的自然数A和B,如果整数A的全部因子(包括1,不包括A本身)之和等于B;且整数B的全部因子(包括1,不包括B本身)之和等于A,则将整数A和B称为亲密数。求3000以内的全部亲密数。
样例输出:
(220,284)(1184,1210)(2620,2924)
提示:
按照亲密数定义,要判断数a是否有亲密数,只要计算出a的全部因子的累加和为b,再计算b的全部因子的累加和为n,若n等于a则可判定a和b是亲密数。计算数a的各因子的算法:
用a依次对i(i=1~a/2)进行模运算,若模运算结果等于0,则i为a的一个因子;否则i就不是a的因子。
代码思路:
本题的难点在于如何得到因子相加,我的思路就是用for循环的方式,如果n%i==0,说明 i 是 n 的因子,然后将其相加即可。注意在写代码时不能忽略 a<b 这个细节
代码表示:
int getSum(int n) { int sum = 0, i; for (i = 1; i < n; i++) { if (n % i == 0) sum += i; } return sum; } void solve() { /*********Begin*********/ int a, b; for (a = 2; a <= 3000; a++) { b = getSum(a); if (a == getSum(b) && a < b) printf("(%d,%d)", a, b); } /*********End**********/ } int main(void) { solve(); return 0; }
第6关:公约公倍数:
题目:
题目描述:写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入。
样例输入:
6 15
样例输出:
3 30
提示:
负数没有最大公约数和最小公倍数;
最大公约数和最小公倍数一定为正数,不可以为负数;
需要考虑代码运行效率,否则会评测超时。
代码思路:
最大公因数求法:
辗转相除法:也叫欧几里得算法,是求最大公因数最常用的方法。假设需要求出整数a和b的最大公因数,我们用a除以b得到余数c,然后将b赋值为a,将c赋值为b,重复这个过程直到余数为0,此时的b就是a和b的最大公因数。例如,求出84和36的最大公因数:首先84除以36得到余数12,于是将36赋值为84,将12赋值为36,继续进行36除以12得到余数0,此时的36就是84和36的最大公因数。
最小公倍数求法:
两个数的乘积等于这两个数的最大公约数与最小公倍数的乘积。假设有两个数是a、b,它们的最大公约数是p,最小公倍数是q。那么有这样的关系:ab=pq。
代码表示:
#include<stdio.h> //编写最大公约数GCD函数 /*********Begin*********/ long long gcd(long long n, long long m) { int t, r; if (n > m) { t = n; n = m; m = t; } while ((r = m % n) != 0) { m = n; n = r; } return(n); } /*********End**********/ //编写最小公倍数LCM函数 /*********Begin*********/ long long lcm(long long n, long long m) { return n / gcd(n, m) * m; } /*********End**********/ int main() { /*********Begin*********/ long long n, m; scanf("%lld%lld", &n, &m); if (n < 0 || m < 0) printf("Input Error\n"); else printf("%lld %lld\n", gcd(n, m), lcm(n, m)); /*********End**********/ return 0; }