《妙趣横生的算法》(C语言实现)- 第5章 数学趣题(一)

5.1 舍罕王的失算

【题目要求】

舍罕是古印度的国王,据说他十分好玩,宰相达依尔为讨好国王,发明了现今的国际象棋献给国王。舍罕非常喜欢这项游戏,于是决定嘉奖达依尔,许诺可以满足达依尔提出的任何要求。达依尔指着舍罕王前面的棋盘提出了要求:“陛下,请您按棋盘的格子赏赐我一点麦子吧,第1个小格赏我一粒麦子,第2个小格赏我两粒,第3个小格赏我四粒,以后每一个小格都比前一个小格赏的麦粒数增加一倍,只要把棋盘上全部64个小格按这样的方法得到的麦粒都赏赐给我,我就心满意足了。”舍罕王听了达依尔这个“小小”的要求,想都没想就满口答应下来。结果在给达依尔麦子时舍罕惊奇地发现它要给达依尔的麦子比自己想象的要多得多,于是他进行了计算,结果令他大惊失色。问题是:舍罕王的计算结果是多少粒麦子?

【实现代码】

// 舍罕王的失算
# include <stdio.h>
int main()
{
    unsigned long long int s = 0, p = 1; // 变量s记录赏赐的总的麦粒数,变量p记录第i个小格赏的麦粒数 
    for (int i = 1; i <= 64; ++i) { // 共有64个格子,使用for循环 
        s += p; // 累加求和 
        p *= 2; // 每一小格都比前一个小格赏的麦粒数增加一倍 
    }
    printf("%llu", s); // 输出结果 
    return 0;
} 
// 运行结果:18446744073709551615 

【总结】

数据范围很大,使用unsigned long long int类型可满足要求。
另外,想清楚循环了多少次。

5.2 求两个数的最大公约数和最小公倍数

【题目要求】

编写一个程序计算两个正整数的最大公约数和最小公倍数。

【实现代码】

// 计算两个正整数的最大公约数和最小公倍数
# include <stdio.h>
int main()
{
    int a, b; // 声明变量记录两个正整数
    printf("Please input two numbers:");
    scanf("%d%d", & a, & b); // 输出两个正整数
    
    for (int i = (a <= b ? a : b); i > 0; --i) { // 计算最大公约数 
        if (a % i == 0 && b % i == 0) {
            printf("the greatest common division of %d and %d is %d\n", a, b, i);
            break;
        }
    }

    for (int i = (a >= b ? a : b); ; ++i) { // 计算最小公倍数 
        if (i % a == 0 && i % b == 0) {
            printf("the least common multiple of %d and %d is %d\n", a, b, i);
            break;
        }
    }
    return 0;
}

【总结】

可直接利用for循环解决问题,不过有些费时。欧几里得算法应该会快一些吧。

5.3 哥德巴赫猜想的近似证明

【题目要求】

所谓哥德巴赫猜想是说任何一个大于2的偶数都能表示成为两个素数之和。应用计算机工具可以很快地在一定范围内验证哥德巴赫猜想的正确性。请编写一个C程序,验证指定范围内哥德巴赫猜想的正确性,也就是近似证明哥德巴赫猜想(因为不可能用计算机穷举出所有正偶数)。

【实现代码】

// 哥德巴赫猜想的近似证明
// 验证1-100中大于2的偶数是否都能表示为两个素数之和
# include <stdio.h>
# include <math.h>

int isprime(int n) // 判断素数 
{
    int res = 1;
    if (n == 1) { // 1不是素数 
        res = 0;
    }
    for (int i = 2; n > 2 && i <= sqrt(n); ++i) { // 2是素数
        if (n % i == 0) { // 有除1和本身之外的因子的数也不是素数 
            res = 0;
            break;
        }
    }
    return res;
}

int main()
{
    int k = 0;
    for (int i = 1; i <= 100; ++i) { // 遍历1-100这100个数 
        if (i <= 2 || i % 2) { // 小于2或者是奇数要排除掉 
            continue;
        }
        for (int j = 2; j <= i - 2; ++j) {
            if (isprime(j) && isprime(i - j)) {
                printf("%2d = %2d + %2d", i, j, i - j);
                ++k; // 变量k用来控制输出格式 
                if (k == 5) {
                    printf("\n");
                    k = 0;
                } else {
                    printf("\t");
                }
                break;
            }
        }
    }
    return 0;
} 

【总结】

复习了判断素数的函数。

5.4 三色球问题

【题目要求】

有红、黄、绿三种颜色的球,其中红球3个,黄球3个,绿球6个。现将这12个球混放在一个盒子中,从中任意摸出8个球,编程计算摸出球的各种颜色搭配。

【实现代码】

// 三色球问题
# include <stdio.h>
int main()
{
    for (int i = 0; i <= 3; ++i) { // 红球有3个,那么有4种可能性被拿出来 
        for (int j = 0; j <= 3; ++j) { // 黄球有3个,那么有4种可能性被拿出来 
            for (int k = 0; k <= 6; ++k) { // 绿球有6个,那么有7种可能性被拿出来 
                if (i + j + k == 8) { // 约束条件:任意拿出8个球 
                    for (int r = 0; r < i; ++r) { // 输出结果 
                        printf("red ");
                    }
                    for (int r = 0; r < j; ++r) {
                        printf("yellow ");
                    }
                    for (int r = 0; r < k; ++r) {
                        printf("green ");
                    }
                    printf("\n");
                }
            }
        }
    }
    return 0;
} 

【总结】

穷举法解决问题。

5.5 百钱买百鸡问题

【题目要求】

我国古代数学家张丘建在《算经》一书中曾提出过著名的“百钱买百鸡”问题。该问题叙述如下:鸡翁一,值钱五;鸡母一,值钱三;鸡雏三,值钱一;百钱买百鸡,则翁、母、雏各几何?请编写C程序,解决“百钱买百鸡”问题。

【实现代码】

// 百钱买百鸡问题
# include <stdio.h>
int main()
{
    int a, b, c; // 三个变量分别表示公鸡、母鸡、小鸡的数目
    for (int a = 0; a <= 100 / 5; ++a) { // 100元最多买100 / 5 = 20只公鸡 
        for (int b = 0; b <= 100 / 3; ++b) { // 100元最多买100 / 3 = 33只母鸡 
            for (int c = 0; c <= 300; ++c) { // 100元最多买100 * 3 = 300只小鸡 
                if (c % 3 == 0 && a + b + c == 100 && 5 * a + 3 * b + c / 3 == 100) { // 判断是否花了100元买了100只鸡,小鸡的数目要是3的倍数
                    printf("a = %d, b = %d, c = %d\n", a, b, c);
                }
            }
        }
    } 
    return 0;
} 

【总结】

穷举法解决问题。

5.6 判断回文数字

【题目要求】

有这样一类数字,它们顺着看和倒着看是相同的数,例如121、656、2332等,这样的数字叫做回文数字。编写一个程序,判断从键盘接收的数字是否为回文数字。

【实现代码】

// 判断回文数字
# include <stdio.h>
int main()
{
    int num;
    printf("please input a number:");
    scanf("%d", & num); // 输入正整数 
    int tmp = num, s = 0;
    while (tmp) { // 计算逆序数 
        s = s * 10 + tmp % 10;
        tmp /= 10;
    }
    if (s == num) { // 逆序数等于数字本身,那就是回文数字 
        printf("%d is a palindrome figures\n", num);
    } else {
        printf("%d is not a palindrome figures\n", num);
    }
    return 0;
} 

【总结】

回文数字、回文字符串一类题型,清楚回文的含义。

5.7 填数字游戏求解

【题目要求】

有这样一个算式:ABCD * E = DCBA,其中ABCDE代表的数字各不相同。编写一个程序,计算出ABCDE各代表什么数字。

【实现代码】

// 填数字游戏求解
# include <stdio.h>
int main()
{
    for (int a = 1; a < 10; ++a) {
        for (int b = 0; b < 10; ++b) {
            if (b == a) { 
                continue;
            }
            for (int c = 0; c < 10; ++c) {
                if (c == b || c == a) {
                    continue;
                }
                for (int d = 1; d < 10; ++d) {
                    if (d == a || d == b || d == c) {
                        continue;
                    }
                    for (int e = 1; e < 10; ++e) {
                        if (e == a || e == b || e == c || e == d) {
                            continue;
                        }
                        int tmp = (a*1000 + b*100 + c*10 + d) * e;
                        if (tmp%10 == a && tmp%100/10 == b && tmp%1000/100==c && tmp/1000 == d) {
                            printf("A = %d, B = %d, C = %d, D = %d, E = %d\n", a, b, c, d, e);
                            printf("%d%d%d%d\n", a, b, c, d);
                            printf("*  %d\n", e);
                            printf("----\n");
                            printf("%d%d%d%d", d, c, b, a);
                            return 0;
                        }
                    }
                }
            }
        }
    }
    return 0;
}

【总结】

仔细观察可发现DCBA是ABCD的逆序数,可以用回文解决问题。

5.8 新郎和新娘

【题目要求】

3对新婚夫妇参加婚礼,3个新郎为A、B、C,3个新娘为X、Y、Z。有人不知道谁和谁结婚,于是询问了6位新人中的3位,但听到的回答是这样的:A说他将和X结婚;X说她的未婚夫是C;C说他将和Z结婚。这人听后知道他们在开玩笑,全是假话。请编程找出谁将和谁结婚。

【实现代码】

// 新郎和新娘
# include <stdio.h>

// 根据题目的叙述筛选除符合要求的答案
int match (int i, int j, int k, char wife[])
{
    if (wife[i] == 'X') { // A不和X结婚 
        return 0;
    }
    if (wife[k] == 'X') { // X不和C结婚 
        return 0;
    }
    if (wife[k] == 'Z') { // C不和Z结婚 
        return 0;
    }
    return 1; 
} 

int main()
{
    char husband[3] = {'A', 'B', 'C'};
    char wife[3] = {'X', 'Y', 'Z'};
    for (int i = 0; i < 3; ++i) { // 新郎A 
        for (int j = 0; j < 3; ++j) { // 新郎B 
            if (j == i) { // 不能1个新娘与2个新郎配对 
                continue;
            }
            for (int k = 0; k < 3; ++k) { // 新郎C 
                if (k == i || k == j) { // 不能1个新娘与2个新郎配对 
                    continue; 
                }
                // 三重循环,可以得到3*2*1 = 6种配对方案
                // 根据题目的叙述筛选除符合要求的答案
                if (match(i, j, k, wife)) { // 得到一种配对方式 
                    printf("husband  wife\n");
                    printf("A------%c\n", wife[i]);
                    printf("B------%c\n", wife[j]);
                    printf("C------%c\n", wife[k]);
                }
            }
        }
    }
    return 0;
} 

【总结】

不知道怎么把约束条件写出来诶,如何使用约束条件用程序写出来。

5.9 爱因斯坦的阶梯问题

【题目要求】

爱因斯坦曾出过这样一道有趣的数学题:有一个长阶梯,若每步上2阶,最后剩1阶;若每步上3阶,最后剩2阶;若每步上5阶,最后剩4阶;若每步上6阶,最后剩5阶;只有每步上7阶,最后刚好一阶也不剩。请问该阶梯至少有多少阶?编写一个C程序解决该问题。

【实现代码】

// 爱因斯坦的阶梯问题
# include <stdio.h>
int main()
{
    for (int i = 1; ; ++i) {
        if (i % 2 == 1 && i % 3 == 2 && i % 5 == 4 && i % 6 == 5 && i % 7 == 0) {
            printf("该阶梯至少有%d阶\n");
            break;
        }
    }
    return 0;
} 
// 运行结果:119

【总结】

穷举法。

5.10 寻找水仙花数

【题目要求】

如果一个3位数等于其各位数字的立方和,则称这个数为水仙花数。例如:407=444+000+777,因此407就是一个水仙花数。编写一个程序,找出全部的水仙花数。

【实现代码】

// 寻找水仙花数
# include <stdio.h>
int main()
{
    for (int i = 100; i < 1000; ++i) { // 三位数 
        int a = i / 100; // 百位 
        int b = i / 10 % 10; // 十位 
        int c = i % 10; // 个位 
        if (i == a*a*a + b*b*b + c*c*c) { // 是水仙花数要输出 
            printf("%d\n", i);
        }
    }
    return 0;
} 

【总结】

穷举法。

5.11 猴子吃桃问题

【题目要求】

有一只猴子第一天摘下若干个桃子,当即吃掉了一半,又多吃了一个;第二天又将剩下的桃子吃掉了一半,又多吃了一个;按照这样的吃法每天都吃前一天剩下的桃子的一半又一个。到了第十天,就只剩下一个桃子了。问题:这只猴子第一天摘了多少个桃子。

【实现代码】

// 猴子吃桃问题
# include <stdio.h>
int main()
{
    int s = 1; // 第十天只剩下一个桃子
    for (int i = 0; i < 9; ++i) { // 前九天计算桃子数量
        s = 2 * (s + 1);
    }
    printf("这只猴子第一天摘了%d个桃子。", s); // 输出结果
    return 0;
} 
// 这只猴子第一天摘了1534个桃子。

【总结】

递推。

5.12 兔子产仔问题

【题目要求】

13世纪意大利数学家斐波那契他的《算盘书》中提出这样一个问题:有人想知道一年内一对兔子可繁殖成多少对,便筑了一道围墙把一对新生的兔子关在里面。已知一对两个月大的兔子以后每一个月都可以生一对小兔子,而一对新生的兔子出生两个月后才可以生小兔子(例如:1月份出生,3月份才可产仔)。假如一年内没有发生死亡,则一年内共能繁殖成多少对?

【实现代码】

// 兔子产仔问题
# include <stdio.h>
int main()
{
    int a = 1, b = 1, s = 0; // 第一月和第二月只有1对兔子 
    for (int i = 3; i <= 12; ++i) { 
        s = b + a; // 从第三月起,每月的兔子数量是前两个月的兔子数量之和 
        a = b; // 前一个月的兔子数量 
        b = s; // 前两个月的兔子数量 
    }
    printf("一年内一对兔子可繁殖成%d对。", s); // 输出 
    return 0;
} 
// 144

【总结】

递推。求第12个月的兔子数量,不是累加每个月的兔子数量哦。

5.13 分解质因数

【题目要求】

根据数论的知识可知任何一个合数都可以写成几个质数相乘的形式,这几个质数都叫做这个合数的质因数。例如24=222*3。把一个合数写成几个质数相乘的形式表示,叫做分解质因数。对于一个质数,它的质因数可定义为它本身。编写一个程序实现分解质因数。

【实现代码】

// 分解质因数
# include <stdio.h>
# include <math.h>

int isprime(int n)
{
    int res = 1;
    if (n <= 1) {
        res = 0;
    }
    for (int i = 2; n > 2 && i <= sqrt(n); ++i) {
        if (n % i == 0) {
            res = 0;
            break;
        }
    }
    return res;
}

int main()
{
    int num;
    printf("Please input a number:");
    scanf("%d", & num);
    printf("%d = ", num);
    int k = 0;
    if (isprime(num)) { // 素数直接输出 
        printf("%d\n", num);
    } else { // 合数进行分解 
        for (int i = 2; ; ++i) {
            if (isprime(i) && num % i == 0) {
                ++k;
                if (k > 1) {
                    printf("*");
                } 
                printf("%d", i);
                num /= i;
                i = 1; // 下次循环依然从2开始判断是不是质因数
                if (num == 1) {
                    break;
                }
            }
        }
    }
    return 0;
} 

【总结】

判断素数函数要清楚。

5.14 常胜将军

【题目要求】

现有21根火柴,两人轮流取,每人每次可以取走1至4根,不可多取,也不能不取,谁取最后一根火柴谁输。请编写一个程序进行人机对弈,要求人先取,计算机后取;计算机一方为“常胜将军”。

【实现代码】

// 常胜将军
# include <stdio.h>
int main()
{
    int computer, people, spare = 21;
    printf("--------------------------------\n");
    printf("---- 你不能战胜我,不信试试 ----\n");
    printf("Game begin:\n\n");

    while (1)
    {
        printf("---- 目前还有火柴 %d 根 ----\n", spare);
        printf("People:");
        scanf("%d", & people);
        if (people < 1 || people > 4 || people > spare) {
            printf("你违规了,你取的火柴数有问题!\n\n");
            continue;
        }
        spare -= people;
        if (spare == 0) {
            printf("\nComputer win! Game Over!\n");
            break;
        }
        computer = 5 - people;
        spare -= computer;
        printf("Computer:%d\n", computer);
        if (spare == 0) {
            printf("\nPeople win! Game Over!\n");
            break;
        }
    }
    return 0;
} 

【总结】

没有想法!怎么实现这个程序啊??
21根火柴,在人先取,计算机后取,每次取1-4根的前提下,只要保证每一轮的抽取(人先取一次,计算机再取一次)人抽到的火柴数与计算机抽到的火柴数之和为5就可以实现计算机的常胜不败。

5.15 求圆周率的近似值

【题目要求】

编写一个C程序,用来求出圆周率的近似值。

【实现代码】

// 计算圆周率的近似值
# include <stdio.h>
# include <math.h>

double getPI(int n);

int main()
{
    int n;
    double PI;
    printf("Please enter accuracy\n");
    scanf("%d", & n);
    PI = getPI(n);
    printf("The similar value of PI is \n%f\n", PI);
    return 0;
}

double getPI(int n)
{
    int div, i = 4;
    double b = sqrt(2) / 2.0;
    double c = 0.0;
    for (div = 0; div < n; ++div) {
        b = sqrt(2.0 - 2.0 * sqrt(1.0 - b * b)) * 0.5;
        i *= 2;
    }
    c = b * i;
    return c;
}

【总结】

计算圆周率的方法有许多,比如正多边形逼近、应用数值概率算法。

5.16 魔幻方阵

【题目要求】

所谓魔幻方阵是指在nn的矩阵中填写1-nn这些数字,使得它的每一行、每一列、以及两个对角线之和均相等。编写程序,打印出一种三阶的魔幻方阵。

【实现代码】

// 魔幻方阵
# include <stdio.h>
int main()
{
    for (int a1 = 1; a1 < 10; ++a1) {
        for (int a2 = 1; a2 < 10; ++a2) {
            if (a1 == a2) {
                continue;
            }
            for (int a3 = 1; a3 < 10; ++a3) {
                if (a3 == a2 || a3 == a1) {
                    continue;
                }
                for (int a4 = 1; a4 < 10; ++a4) {
                    if (a4 == a3 || a4 == a2 || a4 == a1) {
                        continue;
                    }
                    for (int a5 = 1; a5 < 10; ++a5) {
                        if (a5 == a4 || a5 == a3 || a5 == a2 || a5 == a1) {
                            continue;
                        }
                        for (int a6 = 1; a6 < 10; ++a6) {
                            if (a6 == a5 || a6 == a4 || a6 == a3 || a6 == a2 || a6 == a1) {
                                continue;
                            }
                            for (int a7 = 1; a7 < 10; ++a7) {
                                if (a7 == a6 || a7 == a5 || a7 == a4 || a7 == a3 || a7 == a2 || a7 == a1) {
                                    continue;
                                }
                                for (int a8 = 1; a8 < 10; ++a8) {
                                    if (a8 == a7 || a8 == a6 || a8 == a5 || a8 == a4 || a8 == a3 || a8 == a2 || a8 == a1) {
                                        continue;
                                    }
                                    for (int a9 = 1; a9 < 10; ++a9) {
                                        if (a9 == a8 || a9 == a7 || a9 == a6 || a9 == a5 || a9 == a4 || a9 == a3 || a9 == a2 || a9 == a1) {
                                            continue;
                                        }
                                        int r1 = a1 + a2 + a3;
                                        int r2 = a4 + a5 + a6;
                                        if (r1 != r2) {
                                            continue;
                                        }
                                        int r3 = a7 + a8 + a9;
                                        if (r3 != r2) {
                                            continue;
                                        }
                                        int c1 = a1 + a4 + a7;
                                        if (c1 != r3) {
                                            continue;
                                        }
                                        int c2 = a2 + a5 + a8;
                                        if (c2 != c1) {
                                            continue;
                                        }
                                        int c3 = a3 + a6 + a9;
                                        if (c3 != c2) {
                                            continue;
                                        }
                                        int s1 = a1 + a5 + a9;
                                        if (s1 != c3) {
                                            continue;
                                        }
                                        int s2 = a3 + a5 + a7;
                                        if (s2 != s1) {
                                            continue;
                                        }
                                        printf("%d %d %d\n", a1, a2, a3);
                                        printf("%d %d %d\n", a4, a5, a6);
                                        printf("%d %d %d\n", a7, a8, a9);
                                        return 0;
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return 0;
} 

【总结】

耐心一些,认真一些!

5.17 移数字游戏

【题目要求】

有这样一个包含9个圆圈的数阵,编写一个程序,输出数字每一步的移动过程。

【实现代码】

# include "stdio.h"

void getStep(int m[]) // 显示数阵中数字移动的步骤 
{
    int i, j, tmp;
    for (int i = 0; i < 7; ++i) { // 冒泡排序 
        for (int j = 0; j < 7 - i; ++j) {
            if (m[j] >= m[j + 1]) {
                tmp = m[j];
                m[j] = m[j + 1];
                m[j + 1] = tmp; // 数据的交换
                printf("(%d# --> 0#)\n", j + 1);
                printf("(%d# --> %d#)\n", j + 2, j + 1); // 输出移动步骤 
                printf("(0# --> %d#)\n", j + 2);
            }
        }
    }
    printf("\n");
}

void Print(int m[]) // 打印出当前数阵状态 
{
    printf(" [%d]--[%d]--[%d]\n", m[0], m[1], m[2]);
    printf("  |  %c   %c  | \n", 92, 47);
    printf(" [%d]--[ ]--[%d]\n", m[7], m[3]);
    printf("  |  %c   %c  | \n", 47, 92);
    printf(" [%d]--[%d]--[%d]\n", m[6], m[5], m[4]);
}

int main()
{
    int i, m[8];
    printf("Please input 8 integer (1~8) to arrange this matrix\n");
    for (int i = 0; i < 8; ++i) {
        scanf("%d", & m[i]);
    }
    printf("The initial data matrix is like\n");
    Print(m);
    printf("\nMove Step:\n");
    getStep(m);
    printf("The result of moving is\n");
    Print(m);
    return 0;
} 

【总结】

冒泡排序的思想!!

5.18 数字的全排列

【题目要求】

输入一个数字序列,将该序列进行排列,并输出每一种排列方式。编写一个C程序,实现数字序列的全排列。

【实现代码】

// 数字的全排列
# include <stdio.h>

void Perm(int a[], int n, int s, int r[], int m)
{
    int i, j, k, flg = 0;
    int b[n]; // 数组b存放子序列
    for (i = 0; i < n; ++i) {
        flg = 1;
        r[s] = a[i]; // 复制数列a中第i个元素到数组r
        j = 0;
        for (k = 0; k < n; ++k) { // 产生子序列b 
            if (i != k) {
                b[j] = a[k];
                ++j;
            }
        }
        Perm(b, n - 1, s + 1, r, m); // 全排列子序列b 
    }
    if (flg == 0) { // 得到一种排列结果 
        printf("\n");
        for (k = 0; k < m; ++k) {
            printf("%d ", r[k]); // 输出存放排列结果的数组r中的内容 
        }
        printf("\n");
    }
}

int main()
{
    int n;
    printf("Please input the number of digit in the array\n");
    scanf("%d", & n); // 输入待排列的数列中元素的个数 

    int a[n], r[n];
    printf("Please input a string for array\n");
    for (int i = 0; i < n; ++i) { // 输入数列中的元素(整数) 
        scanf("%d", & a[i]);
    }
    Perm(a, n, 0, r, n); // 全排列操作 
    
    return 0;
}

【总结】

递归思想。

5.19 完全数

【题目要求】

如果一个数恰好等于它的因子之和,那么这个数就被称为完全数。例如6的因子为1,2,3,而6 = 1+2+3,因此6是一个完全数。求出1000以内的完全数。

【实现代码】

// 完全数
# include <stdio.h>
int main()
{
    for (int i = 1; i <= 1000; ++i) { // 1000以内的数字
        int tmp = 0;
        for (int j = 1; j < i; ++j) {
            if (i % j == 0) {
                tmp += j; // 对因子累加求和
            }
        }
        if (tmp == i) {
            printf("%d ", i);
        }
    }
    return 0;
} 

【总结】

对数字的因子累加求和。

5.20 亲密数

【题目要求】

如果整数A的全部因子(包括1,不包括A本身)之和等于B,并且整数B的全部因子(包括1,不包括B本身)之和等于A,则称整数A和B为亲密数。求解3000以内的全部亲密数。

【实现代码】

// 亲密数
# include <stdio.h>
int main()
{
    for (int a = 2; a <= 3000; ++a) {
        int b = 0;
        for (int i = 1; i < a; ++i) {
            if (a % i == 0) {
                b += i;
            }
        }
        int s = 0;
        for (int i = 1; i < b; ++i) {
            if (b % i == 0) {
                s += i;
            }
        }
        if (s == a && a < b) {
            printf("%d %d\n", a, b);
        }
    }
    return 0;
} 

【总结】

对数字的因子累加求和。

总结

加油啊,还是有好多题不会做啊!

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
妙趣横生算法(C语言实现)》可作为算法入门人员的教程,也可以作为学习过C语言程序设计的人士继续深造的理想读物,也可作为具有一定经验的程序设计人员巩固和提高编程水平,查阅相关算法实现和数据结构知识的参考资料,同时也为那些准备参加与算法和数据结构相关的面试的读者提供一些有益的帮助。最大的特色在于实例丰富,材新颖有,实用性强,理论寓于实践之中。理论与实践相结合,旨在帮助读者理解算法,并提高C语言编程能力,培养读者的编程兴,并巩固已有的C语言知识。全书分为2个部分共10章,内容涵盖了编程必备的基础知识(如数据结构、常用算法等),编程实例介绍,常见算法和数据结构面试等。可以使读者开阔眼界,提高编程的兴,提高读者的编程能力和应试能力。 目录: 第1部分 基础篇 第1章 数据结构基础 1.1 什么是数据结构 1.2 顺序表 1.2.1 顺序表的定义 1.2.2 向顺序表中插入元素 1.2.3 从顺序表中删除元素 1.2.4 实例与分析 1.3 链表 1.3.1 创建一个链表 1.3.2 向链表中插入结点 1.3.3 从链表中删除结点 1.3.4 销毁一个链表 1.3.5 实例与分析 1.4 栈 1.4.1 栈的定义 1.4.2 创建一个栈 1.4.3 入栈操作 1.4.4 出栈操作 1.4.5 栈的其他操作 1.4.实例与分析 1.5 队列 1.5.1 队列的定义 1.5.2 创建一个队列 1.5.3 入队列操作 1.5.4 出队列操作 1.5.5 销毁一个队列 1.5.6 循环队列的概念 1.5.7 循环队列的实现 1.5.8 实例与分析 1.6 树结构 1.6.1 树的概念 1.6.2 树结构的计算机存储形式 1.6.3 二叉树的定义 1.6.4.二叉树的遍历 1.6.5 创建二叉树 1.6.6 实例与分析 1.7 图结构 1.7.1 图的概念 1.7.2 图的存储形式 1.7.3 邻接表的定义 1.7.4.图的创建 1.7.5 图的遍历(1)——深度优先搜索 1.7.6 图的遍历(2)——广度优先搜索 1.7.7 实例与分析 第2章 常用的查找与排序方法 2.1 顺序查找 2.2 折半查找 2.3 排序的概述 2.4 直接插入排序 2.5 选择排序 2.6 冒泡排序 2.7 希尔排序 2.8 快速排序 第3章 常用的算法思想 3.1 什么是算法 3.2 算法的分类表示及测评 3.2.1 算法的分类 3.2.2 算法的表示 3.2.3 算法性能的测评 3.3 穷举法思想 3.3.1 基本概念 3.3.2 寻找给定区间的素数 3.3.3 TOM的借书方案 3.4 递归与分治思想 3.4..1 基本概念 3.4.2 计算整数的划分数 3.4.3 递归的折半查找算法 3.5 贪心算法思想 3.5.1 基本概念 3.5.2 最优装船问 3.6 回溯法 3.6.1 基本概念 3.6.2 四皇后问求解 3.7 数值概率算法 3.7.1 基本概念 3.7.2 计算定积分 第2部分 编程实例解析 第4章 编程基本功 4.1 字符类型统计器 4.2 计算字符的ASCII码 4.3 嵌套if.else语句的妙用 4.4 基于switch语句的译码器 4.5 判断闰年 4.6 指针变量作参数 4.7 矩阵的转置运算 4.8 矩阵的乘法运算 4.9 巧用位运算 4.10 文件的读写 4.11 计算文件的大小 4.12 记录程序的运行时间 4.13 十进制/二进制转化器 4.14 打印特殊图案 4.15 打印杨辉三角 4.16 复杂级数的前n项和 4.17 寻找矩阵中的“鞍点” 4.18 n阶勒让德多项式求解 4.19 递归反向输出字符串 4.20 一年中的第几天 第5章 数学(一) 5.1 舍罕王的失算 5.2 求两个数的最大公约数和最小公倍数 5.3 歌德巴赫猜想的近似证明 5.4 三色球问 5.5 百钱买百鸡问 5.6 判断回文数字 5.7 填数字游戏求解 5.8 新郎和新娘 5.9 爱因斯坦的阶梯问 5.10 寻找水仙花数 5.11 猴子吃桃问 5.12 兔子产仔问 5.13 分解质因数 5.14 常胜将军 5.15 求兀的近似值 5.16 魔幻方阵 5.17 移数字游戏 5.18 数字的全排列 5.19 完全数 5.20 亲密数 5.21 数字翻译器 5.22 递归实现数制转换 5.23 谁在说谎 第6章 数学(二) 6.1 连续整数固定和问 6.2 表示成两个数的平方和 6.3 具有特殊性质的数 6.4 验证角谷猜想 6.5 验证四方定理 6.6 递归法寻找最小值 6.7 寻找同构数 6.8 验证尼科彻斯定理 6.9 三重回文数字 6.10 马克思手稿中的数学 6.11 渔夫捕鱼问 6.12 寻

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值