简单常识,与简单数学

计算球的体积

球的体积公式:4/3pir^3

  1. #include<iostream>
  2. #include<iomanip>
  3. #define PI 3.14
  4. using namespace std;
  5. //球的体积公式:4/3*pi*r^3
  6. int main()
  7. {
  8. int r = 0;
  9. cin >> r;
  10. cout << fixed << setprecision(2) << 4.0 / 3 * PI * pow(r, 3) << endl;
  11. return 0;
  12. }

三角形面积

海伦公式:S=√p(p-a)(p-b)(p-c)

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. double a, b, c;
  6. cin >> a >> b >> c;
  7. double s = (a + b + c) / 2;
  8. double area = sqrt(s * (s - a) * (s - b) * (s - c));
  9. cout << fixed << setprecision(2) << area << endl;
  10. return 0;
  11. }

求余数r

余数r:a = k * b + r

  1. #include<iostream>
  2. using namespace std;
  3. //余数r:a = k * b + r,其中k是整数
  4. int main()
  5. {
  6. double a = 73.263;
  7. double b = 0.9973;
  8. cout << a - (int)(a / b) * b << endl;
  9. return 0;
  10. }

时间转换

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n;
  6. cin >> n;
  7. int h = n / 3600;
  8. int m = n % 3600 / 60;
  9. int s = n % 3600 % 60;
  10. printf("%d秒 = %d小时%d分钟%d秒\n", n, h, m, s);
  11. return 0;
  12. }

求闰年

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n;
  6. cin >> n;
  7. if (n % 4 == 0 && n % 100 != 0 || n % 400 == 0)
  8. {
  9. cout << "是闰年" << endl;
  10. }
  11. else
  12. {
  13. cout << "不是闰年" << endl;
  14. }
  15. return 0;
  16. }

与7有关的数

一个正整数,如果它能被7整除,或者它的某一位上的数字为7,则称其为“与7相关”的数。
请编程求出所有小于或等于n的“与7无关”的正整数个数。
输入格式:
一行一个正整数n,2<=n<=10^6
输出格式:
一行一个正整数,表示答案。
样例输入:
21
样例输出:
17

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int n, ans = 0;
  6. cin >> n;
  7. for(int i = 1; i <= n; i++)
  8. {
  9. int flag = 1;
  10. if(i % 7 == 0)
  11. {
  12. continue;
  13. }
  14. int x = i;//是为了不改变i的值
  15. while(x)
  16. {
  17. if(x % 10 == 7)
  18. {
  19. flag = 0;
  20. break;
  21. }
  22. x = x / 10;
  23. }
  24. if(flag)
  25. {
  26. ans++;
  27. }
  28. }
  29. cout << ans << endl;
  30. return 0;
  31. }

求第n位小数的值

a/b,n是小数点后第几位

  1. //自己的写法
  2. #include<iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. double a, b, n;
  7. cin >> a >> b >> n;
  8. double num = a / b;
  9. for (int i = 0; i < n; i++)
  10. {
  11. num = num * 10;
  12. }
  13. cout << (int)num % 10 << endl;
  14. return 0;
  15. }
  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a, b, n, t=0;
  6. cin >> a >> b >> n;
  7. for (int i = 1; i <= n; i++)
  8. {
  9. a = a * 10;
  10. t = a / b;
  11. t = t % 10;
  12. }
  13. cout << t << endl;
  14. return 0;
  15. }

求出数组的最大最小值

  1. #include<iostream>
  2. using namespace std;
  3. inta[100]
  4. int main()
  5. {
  6. int n;
  7. cin >> n;
  8. for(int i = 0; i < n; i++)
  9. {
  10. cin >> a[i];
  11. }
  12. int max = a[0];
  13. int min = a[0];
  14. for(int i = 1; i < n; i++)
  15. {
  16. if(max <= a[i])
  17. max = a[i];
  18. if(min >= a[i])
  19. min = a[i]
  20. }
  21. cout << max << endl;
  22. cout << min << endl;
  23. return 0;
  24. }

数字匹配

输入一组数组,然后输入一个数字,判断该数字是否与数组中的某个数一样,一样输出数字的位置

  1. //自己的写法
  2. #include<iostream>
  3. using namespace std;
  4. int a[10];
  5. int main()
  6. {
  7. int num;
  8. for (int i = 0; i < 10; i++)
  9. {
  10. cin >> a[i];
  11. }
  12. cin >> num;
  13. for (int i = 0; i < 10; i++)
  14. {
  15. if (a[i] == num)
  16. {
  17. cout << (i + 1) << endl;
  18. return 0;
  19. }
  20. }
  21. cout << "not found" << endl;
  22. return 0;
  1. #include<iostream>
  2. using namespace std;
  3. int a[10];
  4. int main()
  5. {
  6. int num;
  7. for (int i = 0; i < 10; i++)
  8. {
  9. cin >> a[i];
  10. }
  11. int flag = 0;//这种插旗思维很重要,经常用到
  12. cin >> num;
  13. for (int i = 0; i < 10; i++)
  14. {
  15. if (a[i] == num)
  16. {
  17. cout << (i + 1) << endl;
  18. flag = 1;
  19. }
  20. }
  21. if (flag == 0)
  22. {
  23. cout << "not found" << endl;
  24. }
  25. return 0;
  26. }

插数字

定义一个6个长度的数组,里面有序排好了5个数(升序),现在插入一个数,使插入后的数组依然有序并输出。
样例输入:
i
2 4 6 8 10
7
样例输出:
2 4 6 7 8 10

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int a[6], i, j;
  6. //1.输入数据
  7. for (i = 0; i < 5; i++)
  8. {
  9. cin >> a[i];
  10. }
  11. int in;
  12. cin >> in;
  13. //2.找到插入的位置(下标号)
  14. for (i = 0; i < 5; i++)
  15. {
  16. if (a[i] > in)
  17. break;
  18. }
  19. //3.在插入之前把插入点之后的数往后移动一位给他空出位置
  20. for (j = 5; j < 5; j--)
  21. {
  22. a[j] = a[j - 1];
  23. }
  24. //4.插入数据
  25. a[i] = in;
  26. for (i = 0; i < 6; i++)
  27. {
  28. cout << a[i] << " ";
  29. }
  30. return 0;
  31. }

元素中相同的数字

找出一个含有10个元素的数组中所有的重复的元素,并输出重复的次数
输入:1 2 3 4 5 1 1 1 3 3
输出:
1:4
3:3
思路:
1.只数当前该数后面有多少个与它相同的数,在数之前看看该数前面有没有与它相同的数,如果有说明之前数过了该数就不用再数。
2.确定有没有重复的数,有重复的数才输出,单个的数不输出。

  1. //自己的写法
  2. #include <iostream>
  3. using namespace std;
  4. int main()
  5. {
  6. int a[10] = { 0 };
  7. for (int k = 0; k < 10; k++)
  8. {
  9. cin >> a[k];
  10. }
  11. int i = 0;
  12. while (i < 10)
  13. {
  14. int num = 1;
  15. for (int j = 0; j < 10; j++)
  16. {
  17. if (a[i] == a[j] && i < j)
  18. {
  19. num++;
  20. }
  21. if (a[i] == a[j] && i > j)
  22. {
  23. break;
  24. }
  25. }
  26. if (num > 1)
  27. {
  28. cout << a[i] << ": " << num << endl;
  29. }
  30. i++;
  31. }
  32. return 0;
  33. }
  1. #include <iostream>
  2. using namespace std;
  3. const int Max = 100;
  4. int main()
  5. {
  6. int a[10],flag1,flag2,count;
  7. for (int i = 0; i < 10; i++)
  8. cin >> a[i];
  9. //统计数组中每个元素出现的次数
  10. for (int i = 0; i < 10; i++)
  11. {
  12. flag1 = 0;
  13. for (int m = 0; m < i; m++)
  14. {
  15. if (a[m] == a[i])
  16. flag1 = 1;
  17. }
  18. if (flag1 == 0)
  19. {
  20. count = 1;
  21. flag2 = 0;
  22. for (int j = i + 1; j < 10; j++)
  23. {
  24. if (a[i] == a[j])
  25. {
  26. count++;
  27. flag2 = 1;
  28. }
  29. }
  30. if (flag2)
  31. cout << a[i] << ": " << count << endl;
  32. }
  33. }
  34. return 0;
  35. }

C++经典数学

穷举法

穷举法基本思想:
列举出所有可能的情况,逐个判断有哪些是符合问题所要求的条件,从而得到问题的全部解答。

搬砖问题

36块转,36人搬,男的搬4块,女的搬3块,2个小孩搬1块
求:一次性搬完要男,女,小孩各多少人

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. //将所有的可能性遍历一遍
  6. int man,woman,chile;
  7. for(man = 1; man < 9; man++)
  8. {
  9. for(woman = 1; woman < 12; woman++)
  10. {
  11. child = 36 - man - woman;
  12. if((man * 4 + woman * 3 +child / 2) == 36 && child % 2 == 0)//因为一块砖要两个小孩搬,所以小孩只能是偶数
  13. {
  14. cout << "man:" << man << " woman:" << woman << " child:" << child << endl;
  15. }
  16. }
  17. }
  18. return 0;
  19. }

谁是凶手

A:不是我
B:是C
C:是D
D:C说谎
已知三个人说了真话,判断到底是谁

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int A, B, C, D;
  6. int killer = 0;
  7. for(killer='A'; killer <='D'; killer++)
  8. {
  9. if((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D'))//这里的条件根据每个人说的话去理解
  10. {
  11. cout << "killer is:" << (char)killer << endl;
  12. }
  13. }
  14. return 0;
  15. }

猜配对

三对情侣参加婚礼,三个新郎为A,B,C,三个新娘X,Y,Z,有人想知道究竟谁和谁结婚,于是就问新人中的三位,
A说:他将和X结婚;
X说:她的未婚夫是C;
C说:他将和Z结婚。
这人事后知道他们说的都是假话,那么究竟谁和谁结婚那?
这里要用到穷举的方法得到结果

  1. #include<iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. int A, B, C;
  6. for(A = 'X'; A <='Z'; A++)
  7. {
  8. for(B ='X'; B <='Z'; B++)
  9. {
  10. for(B ='X'; B <='Z'; B++)
  11. {
  12. if(A != 'X' && C != 'X' && C != 'Z' && A != B && A != C && B != C)//后面加的条件,是因为A与B,B与C,A与C,是不能在一起的
  13. {
  14. printf("%c将嫁给A\n", A);
  15. printf("%c将嫁给A\n", B);
  16. printf("%c将嫁给A\n", C);
  17. }
  18. }
  19. }
  20. }
  21. return 0;
  22. }

枚举法

枚举法基本思路:
(1)确定枚举对象、枚举范围和判定条件;
(2)枚举可能的解,验证是否是问题的解。

皇帝的金币,与乘法表相似

国王给他忠诚的骑士金币。在他服役的第一天,骑士得到一枚金币。在接下来的两天中(服役的第二天和第三天),骑士得到了两枚金币。在接下来的三天中(服役的第四天,第五天,第六天),骑士得到了三枚金币。在接下来的四天中(服役的第七天,第八天,第九天和第十天),骑士得到了四枚金币。这种模式的支付方式是不确定的:在得到了N枚金币后,这个骑士会在接下来的N+1天中每天得到N+1枚金币,N是任意的正整数。
你编的程序会决定这任意一天付给骑士的金币的数目(从第一天开始)
输入描述
输入最少包含一行,但是不要多于21行。输入的每一行(除去最后一行)包含一个可以进行一次程序运行的数字,是一个确切的整数(在1..10000的范围内)代表了天数。输入的最后是以含0的一行为标志的。
输出描述
对应于每一次程序运行对应一行输出。这一行包含对应于输入行的天数,跟着一个空格和在这些天中支付给骑士金币的总数,从第一天开始。

  1. /*
  2. i
  3. 1 1
  4. 2 2 2
  5. 3 3 3 3
  6. 4 4 4 4 4
  7. 5 5 5 5 5 5
  8. 6 6 6 6 6 6 6
  9. 1 2 3 4 5 6 j
  10. */
  11. #include<iostream>
  12. using namespace std;
  13. int main()
  14. {
  15. int i = 1, j, d = 0, n = 0, k;
  16. cin >> k;//输入天数
  17. while(1)
  18. {
  19. for(j = 1; j <= i; j++)
  20. {
  21. d++;//天数,为了i不会被影响
  22. n = n + i;
  23. if(d == k)
  24. {
  25. cout << n << endl;
  26. return 1;
  27. }
  28. }
  29. i++;
  30. }
  31. return 0;
  32. }

小球落地问题

一个小球从100米高度自由落下,每次落地后反跳回原高度的一半,再落下。
求它在第十次落地时,共经过多少米?第十次反弹多高?
输入样例:

输出样例:
总长度是:299.609
第十次落地后弹起的高度是:0.0976562

  1. #include <iostream>
  2. using namespace std;
  3. int main()
  4. {
  5. float h = 100, sum = 100;
  6. int i;
  7. for(i = 1; i <= 9; i++)
  8. {
  9. h = h / 2;
  10. sum = sum + 2 * h;
  11. }
  12. cout << sum << endl;
  13. cout << h / 2 << endl;
  14. return 0;
  15. }

猴子吃桃问题

案例1:

猴子第一天摘下若干个桃子,当即吃了一半,又多吃了一个;第二天早上将剩下的桃子吃掉一半,又多吃了一个,以后每天早上都吃了前一天剩下的一半零一个,到第6天早上想吃时,发现只剩下一个桃子。
问:第一天共摘了多少个桃子。
样例输入:

样例输出:
94

  1. /*
  2. 倒推
  3. day6:1
  4. day5:4
  5. day4:10
  6. day3:22
  7. day2:46
  8. day1:94
  9. 结论:n前=(n这+1)*2
  10. */
  11. #include<stdio.h>
  12. int main()
  13. {
  14. int b = 1;
  15. for (int i = 5; i > 0; i--)//天数递减(倒推计算)
  16. {
  17. b = 2 * (b + 1);
  18. }
  19. printf("猴子有桃子%d\n", b);
  20. return 0;
  21. }

案例2:

海滩上有一堆桃子,五只猴子来分。第一只猴子把这堆桃子平均分为五份,多了一个,这只猴子把多的一个扔入海中,拿走了一份。第二只猴子把剩下的桃子又平均分成五份,又多了一个,它同样把多的一个扔入海中,拿走了一份,第三、第四、第五只猴子都是这样做的,问海滩上原来最少有多少个桃子?

  1. #include<stdio.h>
  2. int main()
  3. {
  4. int i, sum = 0, s;
  5. while(1)
  6. {
  7. s = sum;//防止sum被修改
  8. for(i = 0; i < 5; i++)
  9. {
  10. if((s - 1) % 5 == 0)
  11. {
  12. s = (s - 1) / 5 * 4;
  13. }
  14. else
  15. break;
  16. }
  17. if(i == 5 && s > 0)
  18. break;
  19. sum++;
  20. }
  21. cout << sum << endl;
  22. return 0;
  23. }

斐波那契数列

以兔子繁殖为例子而引入,故又称为“兔子数列”0、1、1、2、3、5、8、13、21、34、……

案例1:

第1项和第2项都是1,从第3项开始,每一项的值等于与它相邻的前两项之和
1,1,2,3,5,8,13,21,34,……
规律:其中一个数 = 前两个数之和
求斐波那契数列的第n项和前n项的和

#include<iostream>
using namespace std;

int main()
{
    int a = 1, b = 1, c = 0, sum = 2, n, temp;
    cin >> n;

    for (int i = 3; i <= n; i++)
    {
        c = a + b;
        a = b;
        b = c;
        sum = sum + c;
    }

    cout << c << " " << sum << endl;

    return 0;
}

案例2:

输入一个数n,输出斐波那契数列的前n项

#include<iostream>
using namespace std;
inta[100]

int main()
{
    a[1] = a[2] = 1;
    if(n == 1)
    {
        cout << "1 ";
        return 0;
    }
    if(n == 2)
    {
        cout << "1 1 ";
    }
    for(i = 3; i <= n; i++)
    {
        a[i] = a[i - 1] + a[i - 2];
        cout << a[i] << " ";
    }

    return 0;
}

奶牛繁殖问题

一只刚出生的奶牛,4年生1只奶牛,以后每一年生1只。
现在给你一只刚出生的奶牛,求20年后有多少奶牛。
样例输入:
20
样例输出:
345
规律:符合斐波那契数列规则
f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11
1 1 1 2 3 4 5 7 10 14 19
fn_4 fn_3 fn_2 fn_1 fn
fn_4 fn_3 fn_2 fn_1 fn
fn_4 fn_3 fn_2 fn_1 fn
fn_4 fn_3 fn_2 fn_1 fn
fn_4 fn_3 fn_2 fn_1 fn
通项公式:fn=fn_1+fn_4 (n>=5)

#include <iostream>
using namespace std;

const int Max = 100;
int main()
{
    int fn, fn_1, fn_2, fn_3, fn_4;
    fn_4 = fn_3 = fn_2 = 1;
    fn_1 = 2;
    fn = 3;

    int n, i;
    cin >> n;

    if (n == 1 || n == 2 || n == 3)
    {
        cout << "fn = 1" << endl;
    }    
    else if (n == 4)
    {
        cout << "fn = 2" << endl;
    }
    else //n>=5
    {
        for (i = 5; i <= n; i++)
        {
            fn = fn_1 + fn_4;
            fn_4 = fn_3;
            fn_3 = fn_2;
            fn_2 = fn_1;
            fn_1 = fn;
        }
        cout << fn << endl;
    }

    return 0;
}

走楼梯问题

一个楼梯有n级,妙妙同学从下往上走,一步可以跨一级,也可以跨两级。
问,他走到n级楼梯有多少种走法?
输入格式:
一行一个整数n,0输出格式:
一行n个整数,之间用一个空格隔开,表示走到第1级、第二级、……第n级
分别有多少种走法。
输入样例:
2
输出样例:
1 2
规律:符合斐波那契数列规则
1个台阶:1步 - 1种方法
2个台阶:2步,1步+1步 - 2种方法
3个台阶:1+1+1,2+1,1+2 - 3种
4个台阶:1+1+1+1+1,1+1+2,1+2+1,2+2,2+1+1 - 5种

#include <iostream>
using namespace std;

const int Max = 100;
int main()
{
    int a[Max], n;
    cin >> n;
    a[1] = 1;
    a[2] = 2;
    for(int i=3;i<=n;i++)
    {
        a[i] = a[i - 1] + a[i - 2];
    }
    for (int i = 1; i <= n; i++)
        cout << a[i] << " ";

    return 0;
}

排序算法

插入排序

从键盘上输入n个整数,对它们进行升序排列然后输出
样例输入:
5
8 6 2 4 1
样例输出:
1 2 4 6 8

#include <iostream>
using namespace std;
int a[100];

int main()
{
    int n, i, j;
    cin >> n;
    for(i = 1; i <= n; i++)//空出第一个位置
    {
        cin >> a[i];
    }

    //插入排序,从第2个元素开始到第n个元素
    for(i = 2; i <= n; i++)
    {
        //把一个值插入到有序的序列中使它依然有序
        if(a[i] < a[i-1])
        {
            a[0] = a[i]; //把待插入值a[i]临时保存在a[0]中

            //寻找插入点
            j = i;
            do
            {
                a[j] = a[j - 1];
                j--;
            } while (a[0] < a[j-1]);

            //插入元素
            a[j] = a[0];
        }
    }

    for(i = 1; i <= n; i++)
    {
        cout << a[i] << " ";
    }

    return 0;
}

冒泡排序

概念:一种排序的方法,对一列数实现按值的升序或者降序排列
10 2 8 3 6 4 5 7 9 1 => 1 2 3 4 5 6 7 8 9 10
推导:

  • 比较相邻的元素,如果第一个比第二个大,就交换他们
  • 对每个相邻元素做同样的工作,执行完后,找到第一个最大值
  • 重复以上步骤,每次比较次数减1,直到不需要比较

image.png
结论:
排序的总轮数 = 元素个数 - 1
每轮对比次数 = 元素个数 - 排序轮数 - 1

#include <iostream>
using namespace std;

const int Max = 100;
int main()
{
    int a[Max], n, i, j;
    //1.输入元素的个数和元素值
    cin >> n;
    for (i = 0; i < n; i++)
        cin >> a[i];

    //2.对数组a中的n个元素进冒泡排序
    for(i = 0; i < n - 1; i++)  //找泡的次数
    {
        //找泡
        for(j = 0; j < n - 1 - i; j++)
        {
                if(a[j] > a[j+1])
                {
                    swap(a[j], a[j + 1]);
                }
        }
    }

    //3.输出排好序的数组
    for (i = 0; i < n; i++)
        cout << a[i] << " ";

    return 0;
}

桶排序

桶排序
1).概念:
一种排序方法,对在一个明显范围内的整型数列可以实现按值的升序或降序排列
2).操作:
对一个整型数列,实现该数列的升序排列
(1).定义一个整型数组,数组的每一个元素都作为一个桶,初始值为0,元素的下标号作为桶的编号.
(2).依次遍历待排序列中的每一个元素,如果找到与桶号相等的元素值,就把该桶里的数字加1
(3).从小到大输出各桶的编号,每个编号输出的次数等于该桶的元素的值,则得到有序的序列.
1 8 8 3 5 7 3 7 7 => 1 3 3 5 7 7 7 8

范围:1~10 找10个桶 int a[10]
桶的编号: 0 1 2 3 4 5 6 7 8 9 (这是数组元素的下标号)
桶 : 口 口 口 口 口 口 口 口 口 口(这是数组元素值,初始为0)
桶内的值: 1 2 1 3 2 (与下标相同的元素有多少个)
=>
1 3 3 5 7 7 7 8 8

//桶排序:有重复元素的用法
#include <iostream>
using namespace std;

const int Max = 110;
int main()
{
    //输入1-10之间的整数,由小到大排序输出
    int a[Max] = { 0 };//初始每个桶的值为1
    int n, i, k;
    cin >> n;//有多少个要判断的数值
    for(i = 1; i <= n; i++)//一开始
    {
        cin >> k;
        a[k]++;//给与值相同下标的桶加1个值,相当于桶里有一个数字k
    }

    for (i = 0; i <= 10; i++)
    {
        while (a[i]--)//比如第3个桶有2个3,要把存储的2个3全部释放出来,就用这个步骤
        {
            cout << i << " ";
        }
    }

    return 0;
}
//简单桶排序
#include <iostream>
using namespace std;

const int Max = 110;
int main()
{
    //输入1-10之间的整数,由小到大排序输出
    int a[Max] = { 0 };//初始每个桶的值为1
    int n, i, k;
    cin >> n;
    for(i = 1; i <= n; i++)//一开始
    {
        cin >> k;
        a[k] = 1;//让桶里的值为1
    }

    for (i = 0; i <= 10; i++)
    {
        if (a[i] == 1)
        {
            cout << i << " ";
        }
    }

    return 0;
}

选择排序

1.原理:
每次从待排序列中找出最小的元素和第一个位置的元素交换

2.操作:
(1)遍历所有的第一个位置
(2)找出待排序列中的最小元素
(3).每次的第一个位置元素和每次的最小元素交换

例如:
输入n个整数,让他们从小到大输出
样例输入:
10

10 9 8 7 6 5 4 3 2 1
1 2 3 4 5 6 7 8 9 10

#include <iostream>
    using namespace std;

    const int Max = 110;
    int main()
    {
        //1.输入数据保存到数组
        int a[Max];
        int n, i, j, min, k;
        cin >> n;
        for (i = 0; i < n; i++)
        {
            cin >> a[i];
        }
        //2.选择排序
        //每次从待排序列中找出最小元素和第一个位置元素交换
        //1).遍历所有的第一个位置
        for (i = 0; i < n - 1; i++)
        {
            //2).找出最小元素
            min = INT_MAX;
            for (j = i; j < n; j++)
            {
                if (a[j] < min)
                {
                    min = a[j];//存放的是最小的数
                    k = j;//k保存的是元素下标
                }
            }
            //3).每次的第一个位置元素和每次的最小值元素交换
            swap(a[i], a[k]);
            //<=>
            //        int temp = a[i];
            //        a[i] = a[k];
            //        a[k] = temp;


        }
        //3.输出数组中的序列
        for (i = 0; i < n; i++)
        {
            cout << a[i] << " ";
        }
        return 0;
    }

二分查找

(1).数列的元素是升序排列
(2).将数列中间位置记录的元素值与查找的元素值比较,如果两者相等,则查找成功
否则利用中间的位置将数列分成前后两个子数列
如果中间位置的记录的元素值大于查找的元素值,则进一步查找前一个子数列
否则进一步查找后一个子数列
(3).重复以上过程,直到找到满足条件的位置便查找成功,或者数列不可再分,此时查找不成功

操作:
(1).对序列进行升序排列
(2).需要设置三个变量left,mid,right分别存储待查找区间的左端点,中间点,右端点.X为要查找的值
(3).当left<=right a[mid]!=X开始二分查找
mid=(left+right)/2

问题:
定义一个含有n个元素的整型数组,从中查找某个值,找到了就输出该值的位置,没有找到就输出”没有找到”
样例输入:
10
11 12 13 14 15 16 17 18 19 20
12
样例输出:
2

#include <iostream>
using namespace std;

const int Max = 110;
int main()
{
    int a[11] = { 0,11,12,13,14,15,16,17,18,19,20 };
    int X = 12;

    int left = 1, right = 10, mid = (left + right) / 2;

    //开始二分查找
    while(a[mid]!=X && left<=right)
    {
        if (a[mid] > X)
            right = mid - 1;
        else
            left = mid + 1;
        mid = (left + right) / 2;
    }

    if (left > right)
        cout << "没有找到" << endl;
    else
        cout << "位置:" << mid << endl;


    return 0;
}

递归

递归函数:一个函数,在函数里面自己调用自己
例:
void func()
{
func();
}
递归三要素:
1.递归关系式:对问题进行递归形式的描述
2.递归函数返回值:确定每一层递归函数应该给上一层返回的信息
3.递归的终止条件:当满足什么情况时以一种特殊的情况处理,而不是以递归关系式处理

求:n!

6!
==
fun(6)
<=>6fun(5)
<=>5
fun(4)
<=>4fun(3)
<=>3
fun(2)
<=>2fun(1)
<=>2
1

fun(n)==n*fun(n-1)

#include <iostream>
using namespace std;
int fun(int n)
{
    if (n == 1)
        return 1;
    return n * fun(n - 1);
}

int main()
{
    cout << fun(6) << endl;
    return 0;
}

利用递归求第n项斐波那契数列的值

样例输入:
6
样例输出:
8

#include <iostream>
using namespace std;
int Fib(int n)
{
    if (n == 1 || n == 2)
        return 1;
    return Fib(n - 1) + Fib(n - 2);

}

int main()
{
    cout << Fib(6) << endl;
    return 0;
}

约瑟夫环(用递归写):

有N只猴子,按照顺时针方向围成一圈选大王(编号从1~n),
从1号开始报数,一直数到m,数到m的猴子退出圈外,
剩下的猴子再接着从1开始报数。
就这样,直到圈内剩下一只猴子的时候,这只猴子就是猴王。
(n<=1000)
样例输入:
6 2
样例输出:
5

#include<iostream>
using namespace std;

int Func(int n, int m)
{
    if(n == 1)
        return 0;
    return (Fun(n - 1, m) + m) % n;
}

int main()
{
    cout << Fun(6, 2) + 1 << endl;
    reutrn 0;
}

猜年龄

有5个人坐在一起,
问第五个人多少岁?他说比第4个人大2岁。
问第4个人岁数,他说比第 3个人大2岁。
问第三个人,又说比第2人大两岁。
问第2个人,说比第一个人大两岁。
最后问第一个人,他说是10岁。请问第五个人多大?
样例输出:
18

#include<iostream>
using namespace std;

int Age(int n)
{
    if(n == 1)
        return 10;
    return 2 + Age(n - 1);
}

int main()
{
    cout << Age(5) << endl;
    reutrn 0;
}

牛生仔问题

一只刚出生的奶牛,4年生1只奶牛,以后每一年生1只。
现在给你一只刚出生的奶牛,求20年后有多少奶牛。

  1 2 3 4 5 6 7 8 9  10 11 12 13 14 15 16 17  18  19  20<br />分析:1 1 1 2 3 4 5 7 10 14 19 26 36 50 69 95 131 181 250 345<br />fn=fn_1+fn_4(n>=5)
#include <iostream>
using namespace std;

int Cow(int n)
{
    if (n < 4)
        return 1;
    return Cow(n - 1) + Cow(n - 4);
}

int main()
{
    cout << Cow(20) << endl;
    return 0;
}

递归数组求和

利用递归,求一个整型数组里所有元素的和?
int a[]={1,2,3,4,5}
样例输出:
15

F(a1,a2,a3….an)=a1+F(a2,a3,…an)

#include <iostream>
using namespace std;


int F(int a[],int start,int end)
{
    if (start == end)
        return a[start];
    return a[start] + F(a, start + 1, end);
}

int main()
{
    int a[] = { 1,2,3,4,5 };
    cout << F(a, 0, 4);

    return 0;
}

递归数组求最大值

利用递归,求一个整型数组里所有元素的最大值?

#include <iostream>
using namespace std;


int F(int a[],int start,int end)
{
    if (start == end)
        return a[start];
    return max(a[start] , F(a, start + 1, end));
}

int main()
{
    int a[] = { 1,2,3,4,5 };
    cout << F(a, 0, 4);

    return 0;
}

不用循环输出1~100

void print(int n)
{
    if(n == 0)
    {
        return;
    }
    print(n - 1);
    cout << n << endl;//因为递归的原则,所有数都被堆积在一起,最后释放的时候从后面往前释放,所以能得到正序输出
}
int main()
{
    print(100);
    return 0;
}