一、任意输入 3 个整数,编程实现对这 3 个整数由小到大进行排序

实现过程:
(1)定义数据类型,本实例中 a、b、c、t 均为基本整型。
(2) 使用输入函数获得任意 3 个值赋给 a、b、c。
(3) 使用 if 语句进行条件判断,如果 a 大于 b,则借助于中间变量 t 互换 a 与 b 值, 依此类推比较 a 与 c、b 与 c,最终结果即为 a、b、c 的升序排列。
(4) 使用输出函数将 a、b、c 的值依次输出。

  1. #include <stdio.h>
  2. int main()
  3. {
  4. int a,b,c,t; /*定义4个基本整型变量a、b、c、t*/
  5. printf("Please input a,b,c:\n"); /*双引号内的普通字符原样输出并换行*/
  6. scanf("%d,%d,%d",&a,&b,&c); /*输入任意3个数*/
  7. if(a>b) /*如果a大于b,借助中间变量t实现a与b值的互换*/
  8. {
  9. t = a;
  10. a = b;
  11. b = t;
  12. }
  13. if(a>c) /*如果a大于c,借助中间变景t实现a与c值的互换*/
  14. {
  15. t = a;
  16. a = c;
  17. c = t;
  18. }
  19. if(b>c) /*如果b大于c,借助中间变量t实现b与c值的互换*/
  20. {
  21. t = b;
  22. b = c;
  23. c = t;
  24. }
  25. printf("The order of the number is:\n");
  26. printf("%d,%d,%d",a,b,c); /*输出函数顺序输出a、b、c的值*/
  27. return 0;
  28. }

二、猴子吃桃问题

猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个。第二天早上又将第一天剩下的桃子吃掉一半,有多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第 10 天早上想再吃时,发现只剩下一个桃子了。编写程序求猴子第一天摘了多少个桃子。
实现过程:
(1) 定义 day、x1、x2 为基本整型,并为 day 和 x2 赋初值 9 和 1。
(2) 使用 while 语句由后向前推出第一天摘的桃子数。
(3) 输出结果。

#include <stdio.h>
int main()
{
    int day,x1,x2;    /*定义 day、x1、x2 3 个变董为基本整型*/
    day=9;
    x2=1;
    while(day>0)
    {
        x1=(x2+1)*2;    /*第一天的桃子数是第二天桃子数加1后的2倍*/
        x2=x1;
        day--;    /*因为从后向前推所以天数递减*/

    }
    printf("the total is %d\n",x1);    /* 输出桃子的总数*/
    return 0;
}

三、冒泡排序

用冒泡排序法对任意输入的 10 个数按照从小到大的顺序进行排序。
实现过程:
通过两个 for 循环实现冒泡排序的全过程,外层 for 循环决定冒泡排序的趟数,内层 for 循环决定每趟所进行两两比较的次数。

#include <stdio.h>
int main(){
    int i,j,t,a[10];    //定义变量及数组为基本整型
    printf("请输入10个数:\n");
    for(i=0;i<10;i++)
        scanf("%d",&a[i]);    //从键盘中输入10个数
    for(i=0;i<9;i++)    //变量i代表比较的趟数
        for(j=0;j<9-i;j++)    //变最j代表每趟两两比较的次数
            if(a[j]>a[j+1])
            {
                t=a[j];    //利用中间变童实现两值互换
                a[j]=a[j+1];
                a[j+1]=t;
            }
            printf("排序后的顺序是:\n");
            for(i=0;i<10;i++)
                printf("%3d",a[i]);    //将冒泡排序后的顺序输出
        printf("\n");
    return 0;
}

四、选择排序

实现过程:
程序中用到T两个 for 循环语句。第一个 for 循环是确定位置的,该位置是存放每次从待排序数列中经选择和交换后所选出的最小数。第二个 for 循环是实现将确定位置上的数与后面待排序区间中的数进行比较的。

#include <stdio.h>
int main()
{
    int i,j,t,a[10];    //定义变量及数组为基本整型
    printf("请输入10个数:\n");
    for(i=0;i<10;i++)
        scanf("%d",&a[i]);    //从键盘中输入要排序的10个数字
    for(i=0;i<9;i++)
        for (j=i+1;j<9;j++)
            if(a[i]>a[j])    //如果前一个数比后一个数大,则利用中间变量t实现两值互换
            {
                t=a[i];
                a[i]=a[j];
                a[j]=t;
            }
    printf("排序后的顺序是:\n");
    for(i=0;i<9;i++)
        printf("%5d", a[i]);    //输出排序后的数组
    printf("\n");
    return 0;
}

五、百钱买百鸡问题

中国古代数学家张丘建在他的《算经》中提出了一个著名的“百钱买百鸡问题”,鸡翁一,值钱五,鸡母一,值钱三,鸡雏三,值钱一,百钱买百鸡,问翁、母、雏各几何?

根据题意设公鸡、母鸡和雏鸡分别为 cock、hen 和 chick,如果 100 元全买公鸡,那么最多能买 20 只,所以 cock 的范围是大于等于 0 且小于等于 20;如果全买母鸡,那么最多能买 33 只,所以 hen 的范围是大于等于 0 且小于等于 33;如果 100 元钱全买小鸡,那么最多能买 99 只(根据题意小鸡的数量应小于 100 且是 3 的倍数)。

在确定了各种鸡的范围后进行穷举并判断,判断的条件有以下 3 点:
(1) 所买的 3 种鸡的钱数总和为 100。
(2) 所买的 3 种鸡的数量之和为 100。
(3) 所买的小鸡数必须是 3 的倍数。
实现过程:

#include <stdio.h>
int main()
{
    int cock,hen,chick;   /*定义变童为基本整型*/

    for(cock=0;cock<=20;cock++)   /*公鸡范围在 0~20 之间*/

    for(hen=0;hen<=33;hen++)   /*母鸡范围在 0~33 之间*/

    for(chick=3;chick<=99;chick++)   /*小鸡范围在 3~99 之间*/

    if(5*cock+3*hen+chick/3==100)   /*判断钱数是否等于 100*/

    if(cock+hen+chick==100)   /*判断购买的鸡数是否等于 100*/

    if(chick%3==0)   /*判断小鸡数是否能被 3 整除*/

    printf("公鸡:%d,母鸡:%d,小鸡:%d\n",cock,hen,chick);

    return 0;
}

QQ截图20211011153122.png

六、n!(n的阶乘)

从键盘输入一个数,求出这个数的阶乘,即 n!。
算法思想
首先要清楚阶乘定义,所谓 n 的阶乘,就是从 1 开始乘以比前一个数大 1 的数,一直乘到 n,用公式表示就是:1×2×3×4×…×(n-2)×(n-1)×n=n!

具体的操作:利用循环解决问题,设循环变量为 i,初值为 1,i 从 1 变化到 n;依次让 i 与 sum 相乘,并将乘积赋给 sum。
① 定义变量 sum,并赋初值 1。
② i 自增 1。
③ 直到 i 超过 n。

#include <stdio.h>
int main()
{
    int i,n;
    int sum=1;
    printf("请输入值:\n");
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        sum=sum*i;
    printf("%d!=%d",n,sum);
    return 0;
}

七、水仙花数(阿姆斯特朗数)

阿姆斯特朗数也就是俗称的水仙花数,是指一个三位数,其各位数字的立方和等于该数本身。例如:153=13+53+33,所以 153 就是一个水仙花数。求出所有的水仙花数。
*算法思想

对于阿姆斯特朗数问题,根据水仙花数的定义,需要分离出个位数、十位数和百位数。然后按其性质进行计算并判断,满足条件则打印输出,否则不打印输出。

因此,阿姆斯特朗数问题可以利用循环语句解决。设循环变量为 i,初值为 100,i 从 100 变化到 1000;依次判断条件是否成立,如果成立则输出,否则不输出。

算法思想具体如下:
① 分离出个位数,算术表达式为:j=i%10。
② 分离出十位数,算术表达式为:k=i/10%10。
③ 分离出百位数,算术表达式为:n=i/100。
④ 判断条件是否成立。若是,执行步骤 ⑤;若不是,执行步骤 ⑥。
⑤ 打印输出结果。
⑥ i 自增 1。
⑦ 转到 ① 执行,直到 i 等于 1000。

其判断的条件为:jjj+kkk+nnn==i。
实现过程:

#include <stdio.h>
int main()
{
    int i,j,k,n;
    for(i=100;i<1000;i++)
    {
        j=i%10;
        k=i/10%10;
        n=i/100;
        if(j*j*j+k*k*k+n*n*n==i)
            printf("%4d\n",i);
    }
    return 0;
}

运行结果:153 370 371 407

八、最大公约数和最小公倍数

从键盘输入两个正整数 a 和 b,求其最大公约数和最小公倍数。
算法思想
利用格式输入语句将输入的两个数分别赋给 a 和 b,然后判断 a 和 b 的关系,如果 a 小于 b,则利用中间变量 t 将其互换。再利用辗转相除法求出最大公约数,进而求出最小公倍数。最后用格式输出语句将其输出。
实现过程:

#include <stdio.h>
int main()
{
  int a,b,c,m,t;
  printf("请输入两个数:\n");
  scanf("%d%d",&a,&b);
  if(a<b)
  {
      t=a;
      a=b;
      b=t;
  }
  m=a*b;
  c=a%b;
  while(c!=0)
  {
      a=b;
      b=c;
      c=a%b;
  }
  printf("最大公约数是:\n%d\n",b);
  printf("最小公倍数是:\n%d\n",m/b);
}

当输入的两个数为 15 和 65 时,打印出的结果如下所示:
最大公约数是:
5
最小公倍数是:
195
当输入的两个数为 16 和 72 时,打印出的结果如下所示:
最大公约数是:
8
最小公倍数是:
144
总结
实例中用到了辗转相除法来求最大公约数。在求最小公倍数时要清楚最大公约数和最小公倍数的关系,即两数相乘的积除以这两个数的最大公约数就是最小公倍数。

九、C语言求自然底数e

自然底数 e=2.718281828…,e 的计算公式如下:
e=1+1/1!+1/2!+1/3!+…
要求当最后一项的值小于 10-10 时结束。

算法思想
使用循环实现累加求和,并在求和后计算下一项所对应的阶乘。
① 用循环语句 while 进行循环控制。判断条件为 1/n>10-10;条件成立则执行 ②,条件不成立执行 ⑤;
② 计算求和 e+=1/n;
③ i 自增 1;
④ 计算下一项所对应的阶乘:n=i*n;
⑤ 结束循环,打印输出结果。

#include <stdio.h>
int main()
{
    float e=1.0,n=1.0;
    int i=1;
    while(1/n>1e-10)
    {
        e+=1/n;
        i++;
        n=i*n;
    }
    printf("e的值是:%f\n",e);
    return 0;
}

运行结果:e的值是2.718282

十、C语言求回文素数

回文素数:指对一个素数n从左到右和从右到左读其结果是一样的,既称为该素数为回文素数。绝对素数—— 一个素数当它的数字位置对换后仍为素数,这样的数称之为绝对素数。
算法思想
输入一个整数,如果为奇数,找出不超过1000的回文素数和不超过100的绝对素数。如果为10-20之间的偶数,将其分解为两个素数之和。

#include<stdio.h>
int prime(int n)
{
    int i;
    for(i=2;i<n;i++)
        if(n%i==0)break;
    return i==n;
}
void main()
{
    int prime(int);
    int n,i;
    printf("输入一个数n: ");
    scanf("%d",&n);
    if(n%2)
    {
        for(i=100;i<1000;i++)
            if(prime(i)&&prime(i%10*100+((i/10)%10)*10+i/100))
                printf("%6d  ",i);
    }
    else if((n>=10)&&(n<=20))
        for(i=2;i<=n/2;i++)
            if(prime(i)&&prime(n-i))
                printf("%d=%d+%d\n",n,i,n-i);
    return;
}

QQ截图20211011183522.png

十一、C语言小写转大写

算法思想
在计算机中,大小写字母的ASCII值差32,字符a的ASCII值为97,字符A的ASCII值为65。

#include <stdio.h>
int main()
{
  char a;
  printf("输入一个小写字母:\n");
  a=getchar();
  printf("转换后的字母为:%c\n",a-32);
  return 0;
}

十二、C语言判断闰年

实例要求从键盘输入任意年份的整数N,通过程序运行判断该年份是否为闰年。
算法思想
判断任意年份是否为闰年,需要满足以下条件中的任意一个:
① 该年份能被 4 整除同时不能被 100 整除;
② 该年份能被400整除。

本实例中使用嵌入式 if-else 语句。

#include <stdio.h>
int main()
{
    int year,a;
    printf("请输人年份:\n");
    scanf("%d",&year);
    if(year%400==0)
        a=1;
    else
    {
        if(year%4==0&&year%100!=0)
            a=1;
        else
            a=0;
    }
    if(a==1)
    {
        printf("%d 此年是闰年\n",year);
    }
    else
    {
        printf("%d 此年非闰年\n",year);
    }
    return 0;
}

十三、矩阵转置

本实例是利用数组解决线性代数中的矩阵转置问题。
设有一矩阵为 m×n 阶(即 m 行 n 列),第 i 行 j 列的元素是 a(i,j),需要将该矩阵转置为 n×m 阶的矩阵,使其中元素满足 b(j,i)=a(i,j)。
算法思想
由数学知识可知,将第一个矩阵的所有元素绕着一条从第一行第一列出发的右下角 45° 的射线做镜面反转,即可得到该矩阵的转置。

#include <stdio.h>
int main()
{
    int i,j,i1,j1,a[10][10],b[10][10];
    printf("请输入行数\n");
    scanf("%d",&i1);
    printf("请输入列数\n");
    scanf("%d",&j1); 
    printf("请输入矩阵的元素\n");
    for(i=0;i<i1;i++)
        for(j=0;j<j1;j++)
            scanf("%d",&a[i][j]);
    printf("你输入的矩阵为:\n");
    for(i=0;i<i1;i++)
    {
        for(j=0;j<j1;j++)
            printf("\t%d",a[i][j]);
        printf("\n");
    }
    for(i=0;i<i1;i++) // 矩阵的转置,行和列互换 
        for(j=0;j<j1;j++)
            b[j][i]=a[i][j];  // 用新的数组存放转置的结果 
    printf("矩阵转置:\n");
    for(i=0;i<j1;i++)
    {
        for(j=0;j<i1;j++)  
            printf("\t%d",b[i][j]); //输出结果 
        printf("\n");
    }
    return 0;
}

QQ截图20211011184727.png

十四、兔子生兔子问题(斐波那契数列)

有一对兔子,从出生后第 3 个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

兔子的规律为数列:1, 1, 2, 3, 5, 8, 13, 21 ….

下面使用了迭代、递归和数组三种解法。
方法一:使用迭代

#include <stdio.h>
int main()
{
    long f1=1, f2=1;  // 兔子的数量 
    int i;  // 循环次数 
    int n;  // 要计算的月份

    printf("输入要计算的月数:");
    scanf("%d", &n);

    // 计算出循环次数 
    if(n%2==1){
        n = (n+1)/2;
    }else{
        n = n/2;
    }

    for(i=1;i<=n;i++){
        printf("第%d个月有%d只\n", i*2-1, f1);
        printf("第%d个月有%d只\n", i*2, f2);

        f1=f1+f2; /*前两个月加起来赋值给第三个月*/
        f2=f1+f2; /*前两个月加起来赋值给第三个月*/
    }
    return 0;
}

QQ截图20211011213508.png
方法二:使用递归

#include<stdio.h>
int Feibonacci(int n){
    if(n==1||n==2)
        return 1;
    else 
        return Feibonacci(n-1)+Feibonacci(n-2);
}
int main(){
    int n;  // 要计算的月份 

    printf("输入要计算的月数:");
    scanf("%d", &n); 

    printf("%d个月的兔子总数为%d\n", n, Feibonacci(n));

    return 0;
}

QQ截图20211011213629.png
方法三:使用数组

#include<stdio.h>
void main()
{
    int a[100] ,i,n;

    printf("请输入月数:");
    scanf("%d",&n);

    a[0]=a[1]=1;
    for(i=2;i<n;i++)
        a[i]=a[i-1]+a[i-2];

    printf("第%d个月的兔子为:%d\n", n, a[n-1]);
}

QQ截图20211011213736.png

十五、获取矩阵的最大值及其下标

算法思想
通过打擂台算法,找到最大值,并且保留最大值的行和列号

#include <stdio.h>
int main()
{
    int a[3][4],i,j,max,max_i=0,max_j=0;
    for(i=0;i<3;i++)
        for(j=0;j<4;j++)
            scanf("%d",&a[i][j]);
    printf("你输入的数组为:\n");
    for(i=0;i<3;i++)
    {  printf("a%d行:  ",i);
        for(j=0;j<4;j++)
            printf("\t%d",a[i][j]);
        printf("\n");
    }
    max=a[0][0];  // 令a[0][0]为最大 
    for(i=0;i<3;i++)
        for(j=0;j<4;j++)
            if(a[i][j]>max)
            {
                max=a[i][j]; // 若出现比max大的,直接就更新max 
                max_i=i;     // 记录行和列 
                max_j=j;
            }
            printf("max=a[%d][%d]=%d\n",max_i,max_j,max);
            return 0;
}

十六、统计单词个数算法

思路:文章中的单词都是用空格间隔开的,换句话说,单词数=空格数+1

#include <stdio.h>
int main(){
    printf("输入一行字符:\n");
    char ch;
    int i,count=0,word=0;
    while((ch=getchar())!='\n')
        if(ch==' ')
            word=0;
        else if(word==0)
        {
            word=1;
            count++;
        }
    printf("总共有 %d 个单词\n",count);
    return 0;
}

运行结果:
QQ截图20211019112348.png

十七、输入一个正整数,逐个逆序输出每一位

输入一个正整数,逐个逆序输出每一位,通过%运算可以找到最后一位,然后输入,实现逆序。

#include <stdio.h> 
int main(){
    int num,result;
    printf("请输入一个数:\n");
  scanf("%d",&num);
  while(num!=0){
    result = num%10;//求个位 
    num = num/10;    //例如num为234,234/10就是23 
    printf("%d",result);// 
  } 
    return 0;
}

运行结果:
QQ截图20211019112610.png

十八、输入一个正整数,求其逆序数

和上一个代码有相似之处,唯一的不同就是该数是不断累加起来的,不是逐个输出

#include <stdio.h> 
int main(){
    int num,result=0;
    printf("请输入一个数:\n");
  scanf("%d",&num);
  while(num!=0){
    result = result*10+num%10;//找到个位数,累加并且*10 
    num = num/10;            // num%10的目的为了方便下次取出个位数 
  }    
  printf("逆序数为:%d",result);
    return 0;
}

十九、用递归的方法将一个整数n转换成字符串

分析:应该将输入的数中的每个数进行剥离,然后从头到尾将每个数字转化为对应的字符。递归函数con需要完成的工作是,当n不是个位数(n/10!=0)的时候,将n/10作为参数进行递归调用函数con,然后将数字n的最后一位数字转化为字符串。因为每次的递归调用con函数,是发生在将n的最后一个数字转化为字符串的操作之前的,所以会依次将数字n的每个数字转化为字符。

#include<stdio.h>
//输入1234 
/*
用递归的方法将一个整数n转换成字符串。
例如,输入438,应输出“438”。n的位数不确定
可以是任意的整数。
*/ 
void con(int n){
  int i;
  if((i=n/10)!=0)
    con(i);
  putchar(n%10+'0'); 
}
int main(){
  int n;
  scanf("%d",&n);
  if(n<0){  //输入的数如果数负数 
       n=-n;  // 就先把负数转化成正数  
       putchar('-'); //直接输入负号 
       con(n);     //调用函数,随后函数会输出字符 
     }else      
        con(n);    //如果函数为正数时,直接调用函数 

     return 0;   
}

二十、求素数的几种方法

素数又称质数。所谓素数是指除了 1 和它本身以外,不能被任何整数整除的数,例如17就是素数,因为它不能被 2~16 的任一整数整除。
思路一:因此判断一个整数m是否是素数,只需把 m 被 2 ~ m-1 之间的每一个整数去除,如果都不能被整除,那么 m 就是一个素数。
思路二:另外判断方法还可以简化。m 不必被 2 ~ m-1 之间的每一个整数去除,只需被 2 ~ 必背C语言算法 - 图9 之间的每一个整数去除就可以了。如果 m 不能被 2 ~ 必背C语言算法 - 图10 间任一整数整除,m 必定是素数。例如判别 17 是是否为素数,只需使 17 被 2~4 之间的每一个整数去除,由于都不能整除,可以判定 17 是素数。
原因:因为如果 m 能被 2 ~ m-1 之间任一整数整除,其两个因子必定有一个小于或等于 必背C语言算法 - 图11,另一个大于或等于 必背C语言算法 - 图12。例如 16 能被 2、4、8 整除,16=28,2 小于 4,8 大于 4,16=44,4=√16,因此只需判定在 2~4 之间有无因子即可。【减少运算时间】

思路一代码(经常考填空题):

#include <stdio.h>
int main(){
    int num,i;  
    printf("输入一个整数:");
    scanf("%d",&num);// 输入的整数
    for(i=2;i<num;i++){
        if(num%i==0)
          break;
    }
    if(i>=num)//i的范围是从2开始到num,如果num不是素数,i的值一定小于num 
        printf("%d是素数。\n", num);
    else
        printf("%d不是素数。\n", num);
    return 0;
}

思路一代码(另一种思路):

#include <stdio.h> 
int pri(int n) {
    if(n<2)//最小的素数为2 小于2的都是不是素数 
    return 0;  
  int i;
    for (i=2;i<=n/2; i++) {
        if (n%i == 0)
          return 0;//不是素数直接返回0
    }
    return 1;//是素数返回1
}
int main(){
    int num;
  scanf("%d",&num);
  if(pri(num))
    printf("%d是素数",num);
  else
    printf("%d不是素数",num);
}

思路二代码(运算最省时间的代码):

#include <stdio.h>
#include <math.h>
void main(){
    int m;  // 输入的整数 
    int i;  // 循环次数
    int k;  // m 的平方根 
    printf("输入一个整数:");
    scanf("%d",&m);
    // 求平方根,注意sqrt()的参数为 double 类型,这里要强制转换m的类型 
    k=(int)sqrt( (double)m );
    for(i=2;i<=k;i++)
        if(m%i==0)
            break;
    // 如果完成所有循环,那么m为素数
    // 注意最后一次循环,会执行i++,此时 i=k+1,所以有i>k 
    if(i>k)
        printf("%d是素数。\n",m);
    else
        printf("%d不是素数。\n",m);

    return 0;
}

求一个范围内素数的代码:

#include<stdio.h>
int main(){
  int i,k,num;
  printf("求多少以内的素数呢?\n");
  scanf("%d",&num); 
  //需要循环嵌套 
  for(i=2;i<=num;i++)
  {
    int p=1; //用p来判断当前数是否是质数 ,p=1是质数,p=0不是质数
    for(k=2;k<i;k++)
    {
      if(i % k == 0)
      {
        p=0;
        break;
      }
    }
    if(p == 1)
      printf("%d ",i);  
  }
}