关于c语言的一些练习题思路和源码分享

一,线段描述

描述

KiKi学习了循环,BoBo老师给他出了一系列打印图案的练习,该任务是打印用“*”组成的线段图案。

输入描述:

多组输入,一个整数(1~100),表示线段长度,即“*”的数量。

输出描述:

针对每行输入,输出占一行,用“*”组成的对应长度的线段。

思路:

①因为不止输出一个‘*’,所以一定会用到循环结构

②输入a,则输出a个*,说明i<a

源码分享:

#include <stdio.h>

int main() 
{
    int a=0;
    while((scanf("%d",&a)!=EOF))
      {
        int i = 0;
        for(i = 0;i<a;i++)
        {
            printf("*");
        }
        printf("\n");
        
      }
    return 0;
}

二,写代码将三个整数数按从大到小输出。

例如:

输入:2 3 1

输出:3 2 1

思路:三个数中,两个数比较,两两交换

代码展示:

#include <stdio.h>
int main()
{
    int a = 2;
    int b = 3;
    int c = 1;
    scanf("%d%d%d",&a, &b,&c);
    if(a<b)
    {
        int tmp = a;
        a = b;
        b = tmp;
    }
    if(a<c)
    {
        int tmp = a;
        a = c;
        c = tmp;
    }
    if(b<c)
    {
        int tmp = b;
        b = c;
        c = tmp;
    }
    printf("a=%d b=%d c=%d\n", a, b, c);
    return 0;
}

三,分数求和

计算1/1-1/2+1/3-1/4+1/5 …… + 1/99 - 1/100 的值,打印出结果

思路:
1. 从上述表达式可以分析出
   a. 该表达式主要由100项,基数项为正,偶数项为负
2. 设置一个循环从1~100,给出表达式中的每一项:1.0/i, 注意此处不能使用1,否则结果全部为0
    然后使用flag标记控制奇偶项,奇数项为正,偶数项为负
    然后将所有的项相加即可

#include <stdio.h>


int  main()
{
	int i = 0;
	double sum = 0.0;
	int flag = 1;
	for(i=1; i<=100; i++)
	{
		sum += flag*1.0/i;
		flag = -flag;
	}
	printf("%lf\n", sum);
	return 0;
}

四,数9的个数

编写程序数一下 1到 100 的所有整数中出现多少个数字9

/*
思路:
1. 给一个循环从1遍历到100,拿到每个数据后进行一下操作
2.  a. 通过%的方式取当前数据的个位,检测个位数据是否为9
         如果是,给计数器加1
    b. 通过/的方式取当前数据的十位,检测十位数据是否是9,
          如果是,给计数器加1
  循环一直继续,直到所有的数据检测完,所有9的个数已经统计在count计数中。
*/
#include <stdio.h>


int main()
{
	int i = 0;
	int count = 0;


	for(i=1; i<=100; i++)
	{
		if(i%10==9)
			count++;
		if(i/10==9)
			count++;
	}
	printf("%d\n", count);
	return 0;
}

五,求最大值

求数组中的最大值

思路:
1. 采用循环的方式输入一个数组
2.将最大值赋值给数组中的一个数,然后将数组中其他数与其进行比较,较大的数再次赋值给max

 

int main()
{
	int arr[10] = {0};
	int i = 0;
	int max = 0;

	for(i=0; i<10; i++)
	{
		scanf("%d", &arr[i]);
	}
	//
	max = arr[0];
	for(i=1; i<10; i++)
	{
		if(arr[i]>max)
			max = arr[i];
	}
	printf("max = %d\n", max);
	return 0;
}

六,x图形

输入描述:

多组输入,一个整数(2~20),表示输出的行数,也表示组成“X”的反斜线和正斜线的长度。

输出描述:

针对每行输入,输出用“*”组成的X形图案。

示例1

输入:

5

复制输出:

*   *
 * * 
  *  
 * * 
*   *
//找到规律是关键,看作一条正斜杠和反斜杠
#include <stdio.h>
int main()
{
  int n = 0;
  while(scanf("%d", &n) != EOF)
  {
      for(int i=0; i<n; i++)  //外循环为行
      {
         for(int j=0; j<n; j++) //内循环为列
         {
             if(i == j || i+j == n-1) 
     //最关键的地方,正斜线为[i][i]处是*, 反斜杠为[i][n-1-j]处是*,一行打印1个或2个*
                 printf("*");
             else
                 printf(" ");
         }
         printf("\n"); //打印完一行,换行
      }
  }
  return 0;
}

七,打印用“*”组成的“空心”正方形图案。

输入描述:

多组输入,一个整数(3~20),表示输出的行数,也表示组成正方形边的“*”的数量。

输出描述:

针对每行输入,输出用“*”组成的“空心”正方形,每个“*”后面有一个空格。

#include <stdio.h>

int main() {
    int a, b;
    int num;
   while( scanf("%d",&num)!=EOF)
   {
    for(a=0;a<num;a++)
    {
        for(b=0;b<num;b++)
        {
            if(a==0||a==num-1||b==0||b==num-1)
            {
                printf("* ");
            }
            else 
            {
                printf("  ");
            }
        }
        printf("\n");
    }
   }
    
    return 0;
}

八,矩阵转置

输入:

2 3
1 2 3
4 5 6

复制输出:

1 4

2 5

3 6

思路:先用for循环输入数据,在用for循环输出,其中行数和列数互换即可

#include <stdio.h>

int main() {
    int m,n;
    while (scanf("%d %d", &m, &n) != EOF)
     {
        int a[10][10] = {0};
        int i = 0,j = 0;
       for(i=0;i<m;i++)
       {
        for(j=0;j<n;j++)
        {
            scanf("%d",&a[i][j]);
        }
        
       }

       for(i=0;i<n;i++)
       {
        for(j=0;j<m;j++)
        {
            printf("%d ", a[j][i]);
        }
        printf("\n");
       }
    }
    return 0;
}

 九,有序序列合并

输入:

5 6
1 3 7 9 22
2 8 10 17 33 44

输出:

1 2 3 7 8 9 10 17 22 33 44
#include <stdio.h>
int main()
{
    int a,b,c[100],temp;
    scanf("%d",&a);
    scanf("%d",&b);
    for(int i=1;i<=a+b;i++){
        scanf("%d",&c[i]);
    }
    for (int i = 1; i <= a+b; i++)
	{
		for (int j = 1; j <= a+b - i; j++)
		{
			if (c[j] > c[j + 1])
			{
				temp = c[j];
				c[j] = c[j + 1];
				c[j + 1] = temp;
			}
		}
	}
    for(int i=1;i<a+b+1;i++){
        printf("%d ",c[i]);
    }
    return 0;
}

十,喝汽水问题

喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以喝多少汽水(编程实现)。

/*
思路:
1. 20元首先可以喝20瓶,此时手中有20个空瓶子
2. 两个空瓶子可以喝一瓶,喝完之后,空瓶子剩余:empty/2(两个空瓶子换的喝完后产生的瓶子) + empty%2(不够换的瓶子)
3. 如果瓶子个数超过1个,可以继续换,即重复2
*/
int main()
{
	int money = 0;
	int total = 0;
	int empty = 0;


	scanf("%d", &money);
	
	//方法1
	total = money;
	empty = money;
	while(empty>1)
	{
		total += empty/2;
		empty = empty/2+empty%2;
	}

    printf("total = %d\n", total);
	return 0;
}

十一,打印水仙花数

作业内容

求出0~100000之间的所有“水仙花数”并输出。

“水仙花数”是指一个n位数,其各位数字的n次方之和确好等于该数本身,如:153=1^3+5^3+3^3,则153是一个“水仙花数”

/*
思路:
此题的关键在于只要知道判断一个数据是否为水仙花数的方式,问题就迎刃而解。假定给定一个数据data,具体检测方式如下:
1. 求取data是几位数
2. 获取data中每个位置上的数据,并对其进行立方求和
3. 对data中每个位上的数据立方求和完成后,在检测其结果是否与data相等即可,
相等:则为水仙花数
否则:不是
具体实现参考以下代码。
*/
#include <stdio.h>
#include <math.h>

int main()
{
	int i = 0;
	for(i=0; i<=99999; i++)
	{
		int count = 1;
		int tmp = i;
		int sum = 0;
		//判断i是否为水仙花数
		//1. 求判断数字的位数
		while(tmp/10)
		{
			count++;
			tmp = tmp/10;
		}
     
		//2. 计算每一位的次方和
		tmp = i;
		while(tmp)
		{
			sum += pow(tmp%10, count);
			tmp = tmp/10;
		}
     
		//3. 判断
		if(sum == i)
			printf("%d ", i);
	}
	return 0;
}

其中pow 函数的解释如下:

在C语言中,`pow()`函数用于计算一个数的指数次幂。它的原型是 `double pow(double base, double exponent)`,其中 `base` 是底数`exponent` 是指数。

例如,如果您想要计算2的3次方,您可以这样做:

#include <stdio.h>
#include <math.h>

int main() {
    double base = 2.0;
    double exponent = 3.0;
    double result = pow(base, exponent);
    printf("The result of the power operation is: %.2f\n", result);
    return 0;
}
//在这个例子中,`result`将是8.00。

需要注意的是,`pow()`函数的结果是`double`类型的,因此可能会出现精度问题。此外,如果底数为负数且指数不是整数,或者底数和指数都是0,或者底数为0且指数为负数,都可能会引发错误。在使用`pow()`函数时,应确保底数和指数都是合理的数值。

十二,二分查找函数实现

#include <stdio.h>

// 二分查找函数
// array:已排序的数组
// left:搜索范围的开始索引
// right:搜索范围的结束索引
// key:要查找的元素
int binarySearch(int array[], int left, int right, int key) {
    while (left <= right) {
        int mid = left + (right - left) / 2;

        // 检查mid是否是要查找的元素
        if (array[mid] == key) {
            return mid;
        }

        // 如果key比mid大,说明它只能在右边的子数组中
        if (array[mid] < key) {
            left = mid + 1;
        }

        // 否则,key只能在左边的子数组中
        else {
            right = mid - 1;
        }
    }

    // 如果元素不存在于数组中
    return -1;
}

int main() {
    int arr[] = {1, 3, 5, 7, 9, 11};
    int n = sizeof(arr) / sizeof(arr[0]);
    int x = 7;

    int result = binarySearch(arr, 0, n - 1, x);

    if (result == -1) {
        printf("元素未在数组中找到。\n");
    } else {
        printf("元素在数组中的索引为 %d。\n", result);
    }

    return 0;
}
```

 在C语言中实现二分查找算法,首先需要确保待搜索的数据集合已经排序。二分查找通过比较中间元素来减少搜索范围,直到找到目标元素或搜索范围为空。以下是一个二分查找函数的实现:

在这个实现中,`binarySearch`函数接受四个参数:一个整型数组`array`,两个整型索引`left`和`right`定义了搜索的范围,以及一个整型值`key`表示要查找的元素。函数返回找到的元素的索引,如果没有找到则返回-1。

请注意,在计算中间索引`mid`时,使用`left + (right - left) / 2`而不是`(left + right) / 2`是为了防止在`left`和`right`很大时导致整数溢出。

十二,素数打印

int is_prime(int n)
{
	int i = 0;
	for (i = 2; i <= sqrt(n); i++)
	{
		if (0 == n % i)
		{
			return 0;
		}
	}
	return 1;
}

十三,数组倒置代码

void Reverse(int arr[], int sz)
{
	int left = 0;
	int right = sz-1;


	while(left<right)
	{
		int tmp = arr[left];
		arr[left] = arr[right];
		arr[right] = tmp;
		left++;
		right--;
	}
}

十三,递归和非递归分别实现求第n个斐波那契数

例如:

输入:5  输出:5

输入:10, 输出:55

输入:2, 输出:1

#include<stdio.h>
//非递归:
int fib(int x)
{
	int i=1;
	int j=1;
	int z=1;
	while(x>0)
	{
		z=i+j;
		i=j;
		z=j;
		x--;
	}
}

int main()
{
	int n = 0;
	scanf("%d",&n);
	int ret = fib(n);
	printf("%d",ret);
	
}

递归:
#include<stdio.h>
int fib(int x)
{
	if(x==1)
       return 1;
    else if(x==2)
       return 2;
    else
       return fib(x-1)+fib(x-2);
}

int main()
{
	int n = 0;
	scanf("%d",&n);
	int ret = fib(n);
	printf("%d",ret);
	return 0;
}

十四, 递归实现n的k次方

#include<stdio.h>
int fib(int n,int k)
{
	if(k==0)
	{
		return 1;
	}
	else
	{
		return n*fib(n,k-1);
	}
}
int main()
{
	int n = 0;
	scanf("%d",&n);
	int k = 0;
	scanf("%d",&k);
	int ret = fib(n,k);
	printf("%d",ret);
	return 0;
}

十四,写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19

输入:1729,输出:19

#include<stdio.h>
DigitSum(int n)
{
	int i=0,k=0;
	while(n)
	{
		i=n%10;
		k+=i;
		n=n/10;
	}
	return k;
}

int main()
{
	int n;
	scanf("%d",&n);
	int sum = DigitSum(n);
	printf("%d",sum);
}

十五,n的阶乘

 在C语言中,计算n的阶乘可以通过递归函数实现。阶乘表示为n!,是从1到n的所有整数的乘积。以下是计算n的阶乘的递归函数实现:

#include <stdio.h>

// 递归函数计算n的阶乘
long long factorial(int n) {
    if (n <= 1) {
        return 1; // 0! 和 1! 都是1
    } else {
        return n * factorial(n - 1); // 递归调用自身计算n-1的阶乘,然后乘以n
    }
}

int main() {
    int n;
    printf("请输入一个非负整数n: ");
    scanf("%d", &n);
    
    if (n < 0) {
        printf("输入错误,阶乘只能计算非负整数。\n");
    } else {
        long long result = factorial(n);
        printf("%d的阶乘是: %lld\n", n, result);
    }
    
    return 0;
}

十六,递归方式实现打印一个整数的每一位

 在C语言中,可以使用递归函数来打印一个整数中的每一位数。递归函数通过不断地调用自己来分解问题,直到达到基本情况。对于打印整数的每一位数,基本情况是当整数减小到0时停止递归。以下是使用递归函数打印整数中每一位数的代码:

#include <stdio.h>

// 递归函数打印整数中的每一位数
void printDigits(int n) {
    if (n > 0) {
        // 先打印最高位的数字
        printDigits(n / 10);
        
        // 打印当前最低位的数字
        printf("%d ", n % 10);
    }
}

int main() {
    int number;
    printf("请输入一个整数: ");
    scanf("%d", &number);
    
    printDigits(number);
    printf("\n");
    
    return 0;
}

十七,不允许创建临时变量,交换两个整数的内容

#include <stdio.h>
int main()
{
	int a = 10;
    int b = 20;
    printf("交换前:a = %d b = %d\n", a,b);
    a = a^b;//a=1
    b = a^b;//1^b==1==a->b=a
    a = a^b;//等价于a=b
    printf("交换后:a = %d b = %d\n", a,b);
	return 0;
}

 在C语言中,按位异或操作通常使用符号`^`进行。按位异或(Bitwise XOR)是一种二进制运算,它对两个数的相应位进行比较:如果两个相应的位相同,则结果为0;如果两个相应的位不同,则结果为1。

下面是一个C语言的示例,演示如何使用按位异或是操作符:

#include <stdio.h>

int main() {
    int a = 5; // 二进制表示为 0101
    int b = 3; // 二进制表示为 0011
    int c;
    
    c = a ^ b; // 按位异或操作,结果为 0110,即十进制的 6
    
    printf("a ^ b = %d\n", c);
    
    return 0;
}

按位异或有一些有趣的性质,例如:
- 任何数和0进行按位异或操作,结果都是它本身。即 `a ^ 0 = a`。
- 按位异或操作具有交换律和结合律。即 `a ^ b = b ^ a` 以及 `(a ^ b) ^ c = a ^ (b ^ c)`。
- 连续两次用同一个数进行按位异或操作,可以得到原数的补码。即 `a ^ a = 0` 以及 `a ^ (a ^ a) = a`。

这些性质使得按位异或在某些特定场景下非常有用,比如在不使用第三个变量的情况下交换两个变量的值,或者加密和解密数据。

十七,在一个整型数组中,只有一个数字出现一次,其他数组都是成对出现的,请找出那个只出现一次的数字。

例如:

数组中有:1 2 3 4 5 1 2 3 4,只有5出现一次,其他数字都出现2次,找出5

运用按位异或操作符运算

#include <stdio.h>

int find_single(int arr[], int sz)
{
    int ret = 0;
    int i = 0;
    for (i = 0; i < sz; i++)
    {
        ret ^= arr[i];
    }
    return ret;
}
int main()
{
    int arr[] = { 1,2,3,4,5,1,2,3,4 };
    int sz = sizeof(arr) / sizeof(arr[0]);
    int single = find_single(arr, sz);
    printf("%d\n", single);


    return 0;
}

注:题目大多数在牛客app查询,这些是比较经典的题目,仅表示个人刷题过程,有疑问的朋友可以在评论区提出

  • 21
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值