经典笔试题

目录

1.输入一些数求最max。

2.分数求和

3.打印闰年

4.打印素数

5.逆序输出

6.有序序列合并

7.逆序方法

8二分查找

9.扫雷游戏

10.喝汽水问题

11.水仙花数问题

12.计算求和

13.计算斐波那契数

14 求n的阶乘

15.打印一个数的每一位

16:计算一个数的每位之和(递归实现)

17.递归实现n的k次方

18.字符串左旋

19.模拟实现strlen函数


1.输入一些数求最max。

6cd7b8b8b3b14948adc87cce96e2de95.png

/*
思路:
1. 采用循环的方式输入一个数组
2. 使用max标记数组中的最大值,采用循环的方式依次获取数组中的每个元素,与max进行比较,如果arr[i]大于    max,更新max标记的最大值,数组遍历结束后,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;
}

2.分数求和

986817393fca4ea0ac321b5943ab4fe5.png

2f75075804474717921d06a977def6b2.png

*
思路:
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;
}

3.打印闰年

6d0cc74689a64271be30f27ef9e86ef7.png

1a396e53401447cdaf54348706ad0de2.png

4.打印素数

6350d5c9da674ed0af214bd9a61aee83.png

打印素数

ffd235870d514acf83ed9c70d4ff263a.png

5.逆序输出

#include <stdio.h>



int main() {

    int i=0;

     int arr[10]={0};

     for(i=0;i<10;i++)

     {

        scanf("%d",&arr[i]);



     }

       for(i=9;i>=0;i--)

     {

      printf("%d ",arr[i]);



     }

     printf("\n");

    return 0;

6.有序序列合并

这段代码实现了将两个已经排好序的数组合并成一个排好序的数组,并且按照题目要求进行了相应的输入输出。核心思想和方法如下:

  1. 读取输入:首先从标准输入中读取两个整数n和m,分别表示两个升序序列的长度,然后分别读取这两个升序序列。

  2. 合并排序:使用两个指针i和j分别代表两个数组的当前位置,通过比较arr1[i]和arr2[j]的大小来决定输出哪一个元素,然后将对应的指针向后移动。这样可以保证输出的序列仍然是升序的。

  3. 输出结果:在合并排序过程中,如果其中一个数组的元素已经全部输出完毕,那么剩下的另一个数组的元素就是已经排好序的,直接输出即可。  比如arr1数组走完了,arr2数组还要元素没有走完,就要判断下标i是否小于n或者j是否小于n

  4. 最后返回0,表示程序顺利执行结束。

总的来说,这段代码实现了简单而高效的合并排序算法,用于将两个有序数组合并成一个有序数组,并且符合了输入输出的格式要求。

394652f029234c4b8eebad731335f0fd.png

#include <stdio.h>
int main() {
    int n = 0;
    int m = 0;
    scanf("%d %d", &n, &m);
    int arr1[n];
    int arr2[m];
    for (int i = 0; i < n; i++) {
        scanf("%d", &arr1[i]);
    }
    for (int i = 0; i < m; i++) {
        scanf("%d", &arr2[i]);
    }
    //合并
    int i=0;
    int j=0;
    while(i<n && j<m)
    {
        if(arr1[i]<arr2[j])
        {
            printf("%d ",arr1[i]);
            i++;
        }
        else {
          printf("%d ",arr2[j]);
            j++;
        }
        
    }
     if(i<n)
     {
        for(;i<n;i++)
        {
            printf("%d ",arr1[i]);

        }
     }
     else {
     for(;j<m;j++)
        {
            printf("%d ",arr2[j]);

        }
     }
    return 0;
}

7.逆序方法

实现原理:

  1. 字符数组:这个程序处理的是一个字符数组,也可以被看作是一个字符串。注意,C语言的字符串以'\0'作为结束标志,所以在计算数组大小时要减去1,排除这个结束标志。

  2. 双指针法:使用两个指针,一个从数组的开始向后移动,一个从数组的结束向前移动。这两个指针分别用于定位要交换的字符。

核心方法:

  1. 初始化指针:首先,我们初始化两个指针,left指向数组的开始,right指向数组的结束(不包括结束标志'\0')。

  2. 循环交换:然后,我们进入一个循环,只要left还在right的左边,就继续循环。在循环中,我们将leftright指向的字符交换。

  3. 交换字符:交换字符是通过创建一个临时变量tep来实现的,用它来保存left指向的字符,然后将right指向的字符赋给left,最后将tep的值赋给right

  4. 移动指针:交换完字符后,我们将left向右移动一位,将right向左移动一位,为下一次交换做准备。

  5. 循环直至两指针相遇或交叉:当leftright相遇或交叉时,说明所有的字符都已经被反转了,我们就完成了任务。

以上就是这段代码的实现原理和核心方法。

6201cc1b0ba54b5cb420c80c83efa512.png

// 编写代码,演示多个字符从两端移动,向中间汇聚  逆序方法
int main()
{
	char arr[] = "abcdef";
	int sz = sizeof(arr) / sizeof(arr[0]);
	int  left = 0;
	int right = sz - 2;
	while (left <= right)
	{
		int tep = arr[left];
		arr[left] = arr[right];
		arr[right] = tep;
		left++;
		right--;
	}
	printf("%s", arr);
	return 0;
}

1c23dac5b9fc4fdcb6bd6825eb3c32f7.png

8二分查找

//二分查找
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int left = 0;
	int right = sz - 1;
	int k = 0;
	scanf("%d", &k);
	while (left <= right)
	{
		int mid = (left + right) / 2;
		if (arr[mid] < k)
		{
			left = mid + 1;
		}
		else if (arr[mid] > k)
		{
			right = right - 1;
		}
		else

		{
			printf("找到到了下标是%d\n", mid);
			break;
		}
		if (left > right)
		{
			printf("找不到了\n");
		}

	}
	return 0;
}

74f72f5c475a483592020756e2d2801e.png

9.扫雷游戏

e26ddb9b8724438ab4ea27016433564e.png

3d46d87c2174416cb1b8b8aeb163e196.png

7ae44bafcacf4719a1f227dde55ba865.png

baa076820fca4f4a9d114f2e6f4852ca.png

124abad49a70437f8d39e141adbc0ce2.png

#define _CRT_SECURE_NO_WARNINGS
#include  "game.h"
void game()
{
	char mine[ROWS][COLS];
	char show[ROWS][COLS];
	//初始化棋盘
	InitBoard(show, ROWS, COLS, '*');
	InitBoard(mine, ROWS, COLS, '0');
	//打印棋盘
	print_Borad(show, ROW, COL);
    // 布置雷
	Getmine(mine, ROW, COL);
	//print_Borad(mine, ROW, COL);
	//排查雷
	Findmine(show, mine, ROW, COL);
}
void mean()
{
	printf("******************\n");
	printf("*******1.play*****\n");
	printf("*******0.exit*****\n");
	printf("******************\n");
}
int main()
{
	int input = 0;
	do
	{
		mean();
		printf("请选择:\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏\n");
			break;
		default:
			printf("选择错误请重新选择\n");
			break;
		}

	} while (input); 
	return 0;
}
#pragma once
#define ROW 9
#define COL 9
#define ROWS ROW+2
#define COLS COL+2
#define EASY_COUNT 10
#include <stdio.h>
#include <math.h>
#include <time.h>
//初始化棋盘
void InitBoard(char arr[ROWS][COLS], char rows, char cols, char cet);
//打印棋盘
void print_Borad(char arr[ROWS][COLS], char row, char col);
// 布置雷
void Getmine(char arr[ROWS][COLS], char row, char col);
//排查雷
void Findmine(char show[ROWS][COLS], char mine[ROWS][COLS],char row, char col);

#define _CRT_SECURE_NO_WARNINGS
#include  "game.h"
//初始化棋盘
void InitBoard(char arr[ROWS][COLS], char rows, char cols, char cet)
{
	int i = 0;
	for (i = 0; i < rows; i++)
	{
		int j = 0;
		for (j = 0; j < cols; j++)
		{
			arr[i][j] = cet;
		}
	}
}
//打印棋盘
void print_Borad(char arr[ROWS][COLS], char row, char col)
{
	printf("---------扫雷--------\n");
	int i = 0;
	//打印列
	for (i = 0; i <= col; i++)
	{
		printf("%d ", i);
	}
	printf("\n");

	for (i = 1; i <= row; i++)
	{
		//打印行
		printf("%d ", i);
		int j = 0;
		for (j = 1; j <= col; j++)
		{
			printf("%c ", arr[i][j]);
		}
		printf("\n");

	}
	printf("---------扫雷--------\n");

}
// 布置雷
void Getmine(char arr[ROWS][COLS], char row, char col)
{
	int count = EASY_COUNT;
	while (count)
	{
		int x = rand() % row + 1;//1-9
		int y = rand() % col + 1;//1-9
		//生成随机数
		//判断是否布置过雷
		if (arr[x][y] == '0')
		{
			arr[x][y] = '1';
		}
		//布置成功count--
		count--;
	}
}
int count_mine(char mine[ROWS][COLS], int x, int y)
{
	return mine[x - 1][y - 1] + mine[x - 1][y]
		+ mine[x - 1][y + 1] + mine[x][y - 1]
		+ mine[x][y + 1] + mine[x + 1][y - 1]
		+ mine[x + 1][y] + mine[x + 1][y + 1] - 8 * '0';
}
//排查雷
void Findmine(char show[ROWS][COLS], char mine[ROWS][COLS], char row, char col)
{
	int x = 0;
	int y = 0;
	int win = 0;
	while (win < row * col - EASY_COUNT)
	{
		printf("输入坐标\n");
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y >= 1 && y <= col)
		{
			if (mine[x][y] == '1')
			{
				printf("你被炸死了\n");
				print_Borad(mine, ROW, COL);
				break;

			}
			else
			{
				//该位置不是雷,就统计这个坐标周围有⼏个雷
				//统计雷的个数
				int n=count_mine(mine, x, y);
				show[x][y] = n + '0';
				print_Borad(show, ROW, COL);
				win++;
			}
		}
		else
		{
			printf("输入坐标非法\n");
		}
	}
	if (win == row * col - EASY_COUNT)
	{
		printf("恭喜你排雷成功\n");

	}
}

10.喝汽水问题

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

//喝汽水,1瓶汽水1元,2个空瓶可以换一瓶汽水,给20元,可以喝多少汽水(编程实现)
int main()
{
	int money = 0;	//	钱
	int count = 0;  //喝汽水的次数
	int kp = 0;    //空瓶个数

	scanf("%d", &money);
	count = money;
	kp = money;
	while (kp>1)
	{
		count += kp / 2;	//	比如有20元 ,就等于喝了20瓶汽水,20空瓶就可以换10瓶汽水
		kp = kp / 2 + kp % 2;//把喝掉的10瓶汽水,就相当于10个空瓶加上上一次比如多出来的空瓶
	}
	printf("%d\n", count);
	return 0;
}

1712f42fa75b4049b020e8d8e7007057.png

9e8eb513280b408183f02438d1786d09.png

总结:

喝的汽水数=2*money-1 当钱数大于0的时候

钱数<=0时,count=0。

11.水仙花数问题

方法1

  1. /题目:打印出所有的"水仙花数",所谓"水仙花数"是指一个三位数,其各位数字立方和等于该数 本身。

  2. //程序分析:利用for循环控制100 - 999个数,每个数分解出个位,十位,百位。

  3. //例如:153是一个"水仙花数",因为153=1的三次方+5的三次方+3的三次方

这段代码是一个寻找水仙花数的程序。水仙花数指的是一个n位数(n≥3),它的每个位上的数字的n次幂之和等于它本身。例如153是一个水仙花数,因为1^3 + 5^3 + 3^3 = 153。

在这段代码中,核心的思想是通过循环遍历0到10000之间的所有数字,针对每个数字进行如下操作:

  1. 计算该数字的位数n。
  2. 计算该数字每一位的n次幂之和。
  3. 判断计算得到的和是否等于该数字本身,如果是则输出该数字。

核心方法是利用循环和数学运算来判断每个数字是否符合水仙花数的定义,并输出符合条件的数字

623deb431fc64095bf3f084efcc65984.png


// 简单版的水仙花数 //三位数
int main()
{
	int i = 0;
	for (i = 100; i < 1000; i++)
	{
		int a = i % 10;//个位
		int b = i / 10 % 10;//十位
		int c = i / 100;//百位
		if (i== a * a * a + b * b * b + c * c * c)
		{
			printf("%d ", i);
		}
	}
	
	return 0;
}

循环出来的数和你分离出来的个位十位百位出来的数进行比较,如果相等就是水仙花数。

输入版简单方法

7a022a6699014c5fa28b8f19d43a7683.png

int main()
{
	int n = 0;
	while (~scanf("%d", &n))
	{
		int a = n % 10;
		int b = n / 10 % 10;
		int c = n / 100;
		if (a * a * a + b * b * b + c * c * c == n)
		{
			printf("是水仙花数\n");
		}
		else
		{
			printf("不是水仙花数\n");

		}
	}
	

	return 0;
}

方法二 通解方法

d3f9760dd50b420fbfb49fcc6f24a267.png

// 万能方法
#include <math.h>
int main()
{
	int i = 0;
	for (i = 0; i <= 10000; i++)
	{
		int tep = i;
		int n = 1;	//任何数至少是一位数
		int sum = 0;
		//计算i的位数
		while (tep / 10)//计算位数
		{
			n++;
			tep /= 10;
		}
		//求分离数来的立方和
		tep = i;//此时的tep==0
		//得出i的每一位,计算它的n的立放次方
		while (tep)
		{
			sum += pow(tep % 10, n);//分离
			tep /= 10;
		}
		if (sum == i)
		{
			printf("%d ", i);
		}
	}
	
	return 0;
}

总结

1.要计算i是几位数

2.然后分离出它的每一位 然后使用pow()来计算它的立方

12.计算求和

//求Sn = a + aa + aaa + aaaa + aaaaa的前5项之和,其中a是一个数字,
//例如:2 + 22 + 222 + 2222 + 22222

6657860fc8b84b2d8dbf165234934cc0.png

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

13.计算斐波那契数

所谓斐波那契数就是前二项相加等于后一项 这个规则只能从第三项开始。

方法1递归方法

b6824a108726425999fbcf9e87503cc9.png

5ed8748c2edc450c9e2b590778b809fc.png

//递归方法
int Fib(int n)
{
	if (n > 2)

		return  Fib(n - 1)+ Fib(n -2);
	else
		return 1;
	
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}

方法2迭代方法

产生新的a和b

09fea1b85ede4c73bc7cd886e5b22973.png

//迭代方法
int main()
{
	int n = 0;
	scanf("%d", &n);
	int a = 1;
	int b = 1;
	int c = 1;
	while (n>=3)
	{
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	printf("%d", c);
	return 0;
}

14 求n的阶乘

方法1 递归方法e1e677bf1b7840c2b1f4d7346f70e53d.png46c6501cbc3d461082aff24f4c199896.png

//递归版本
int Fact(int n)
{
	if (n <= 1)
		return 1;
	else
		return n * Fact(n - 1);
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fact(n);
	printf("%d\n", ret);
	return 0;
}

方法2 迭代方法

118bde07a13e4cbf9d931ae78a96431e.png


//迭代方法
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = 1;//0的阶乘是1
	int sum = 0;
	int i = 0;
	for (i = 1 ;i <=n; i++)
	{
		ret *= i;

	}
	printf("%d", ret);

	return 0;
}

15.打印一个数的每一位

递归方法

54f03fe8a1ee443184f860b8fd22c102.png

81a5dadf1cf7442a84844f9aaef2a4bb.png8afc4cd6c6e34d29be1bac461b63b25e.png

//递归方式实现打印一个整数的每一位
void  print(int n)
{
	
	if (n > 9)
	{
		print(n / 10);
	}
	printf("%d ", n % 10);
	
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	print(n);
	return 0;
}

16:计算一个数的每位之和(递归实现)

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

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

输入:1729,输出:19

a842574462d04bb69cd43893c0b9e66e.png

e0051755fc354d63b4725c385cfdd1b1.png

bfbf14b5bdf84353ae5023efa62437b0.png

int  Fait(int n)
{
	if (n > 9)

		return Fait(n / 10) + (n % 10);
	else
		return n;	
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret=Fait(n);
	printf("%d\n", ret);
	return 0;
}

17.递归实现n的k次方

编写一个函数实现n的k次方,使用递归实现。

2485e71f774d4f6ba48bb6c483bbc5c6.png

750ac1ac8e594247892e3d344c874d46.png

84d22e28ab614a7a84217486f231677b.png

//1 K==0 1
//2 K>0 n*Pow(n,k-1)
//3.k<0 1/pow(n,-k)

double Pow(int n, int k)
{
	if (k == 0)
	{
		return 1;
	}
	else if (k > 0)
	{
		return n * Pow(n, k - 1);
	}
	else
	{
		return 1 / Pow(n, -k);
	}
}
int main()
{
	int n = 0;
	int k = 0;
	scanf("%d %d", &n, &k);
	double ret=Pow(n, k);
	printf("%.2f\n", ret);
	return 0;
}

18.字符串左旋

实现原理:

  1. 字符数组:这个程序处理的是一个字符数组,也可以被看作是一个字符串。注意,C语言的字符串以'\0'作为结束标志,所以在计算数组大小时要减去1,排除这个结束标志。

  2. 旋转次数:用户输入的旋转次数可能会超过字符串的长度,因此我们需要通过模运算来得到实际的旋转次数。

核心方法:

  1. 初始化:首先,我们获取用户输入的旋转次数,并通过模运算得到实际的旋转次数。

  2. 循环旋转:然后,我们进行旋转操作。每次旋转都会将第一个字符移到数组的末尾,剩下的字符依次向前移动一位。这个过程重复k次。

  3. 移动字符:移动字符是通过创建一个临时变量tep来实现的,用它来保存第一个字符,然后将剩下的字符依次向前移动一位,最后将tep的值赋给数组的最后一个字符。

  4. 循环直至完成旋转:当我们完成k次旋转后,就完成了任务。

以上就是这段代码的实现原理和核心方法。

实现一个函数,可以左旋字符串中的k个字符

例如ABCD左旋一个字符得到BCDA

ABCD左旋两个字符得到CDAB

//方法1
void move_zx(char arr[], int k,int sz)
{
	int i = 0;
	int len = sz - 1;//字符串的长度
	k %= len;//  如果用户输入移动的字符大于这个字符串本身长度,就可以进行模运算。
    // k=6%4-----2
	for (i = 0; i < k; i++)
	{
		//1先把首字符放在tep里
		char tep = arr[0];
		//2.再把剩下的元素移到前面来
		int j = 0;
		for (j = 0; j < len - 1; j++) //4个字符首字符已经移到了tep里,剩下3给字符只需移到3次即可
		{
			arr[j] = arr[j + 1];			
		}
		//3.把tep放在最后
		arr[len - 1] = tep;
	}
}
int main()
{
	char arr[] = "ABCD";
	int k = 0;
	scanf("%d", &k);
	int sz = sizeof(arr) / sizeof(arr[0]);
	move_zx(arr, k,sz);
	printf("%s\n", arr);
	return 0;
}

方法2

实现原理:

  1. 字符数组:这个程序处理的是一个字符数组,也可以被看作是一个字符串。

  2. 旋转次数:用户输入的旋转次数可能会超过字符串的长度,因此我们需要通过模运算来得到实际的旋转次数。

核心方法:

  1. 初始化:首先,我们获取用户输入的旋转次数,并通过模运算得到实际的旋转次数。

  2. 分割和反转:然后,我们将字符串分为两部分,前k个字符为一部分,剩下的字符为另一部分。对这两部分分别进行反转。

  3. 整体反转:最后,我们对整个字符串进行反转。

这个方法的关键在于三次反转操作。首先,我们分别反转两部分,然后再反转整个字符串。这样做的结果就是将前k个字符移动到字符串的末尾,而不改变字符之间的相对顺序。

以上就是这段代码的实现原理和核心方法。

void resever(char* left, char* right)
{
	while (left <= right)
	{
		char tep = *left;
		*left = *right;
		*right = tep;
		left++;
		right--;
	}
}
void move_xz(char arr[], int k)
{
	int len = strlen(arr);
	k %= len;
	//1.分二部分 
	resever(arr, k - 1 + arr);
	//2. 逆序
	resever(arr+k, len-1+arr);
	//3.整体逆序
	resever(arr , len-1 + arr);

}
int main()
{
	char arr[] = "ABCD";
	int k = 0;
	scanf("%d", &k);
	move_xz(arr, k);
	printf("%s\n", arr);
	return 0;
}

19.模拟实现strlen函数

递归思想

这里的my_strlen(str+1),str是字符a地址,加一是字符b的地址 1+bc的长度

//模拟实现库函数strlen
//方法1 计算器的方法
//int my_strlen(char* str)
//{
//	int count = 0;
//	while (*str != '\0')
//	{
//		count++;
//		str++;
//
//	}
//	return count;
//}


//方法2 递归思想
//int my_strlen(char* str)
//{
//	if (*str != '\0')
//	{
//		return 1+ my_strlen(str +1);
//	}
//	else
//	{
//		return 0;
//	}
//}

// 方法3 指针-指针的方法

int my_strlen(char* str)
{
	char* star = str;
	while (*str != '\0')
	{
		str++;
	}
	return  str-star;
}
int main()
{
	char arr[100] = { 0 };
	gets(arr);
	int ret=my_strlen(arr);
	printf("%d\n", ret);

	return 0;
}

方法1 核心是要找到起始地址 和\0的关系

从起始地址开始计数,炸到\0就停止计数这个是关键

方法2 递归方法

这里的my_strlen(str+1),str是字符a地址,加一是字符b的地址 1+bc的长度

核心是把起始地址当成1,再加上调用后面字符的地址函数,遇到\0就返回0

方法3 指针-指针

首先找到起始地址,把它赋给一个临时变量,然后让这个指针一直自加,找到\0就不在自加

然后用末端的地址-起始端的地址------>高位的指针-地位的指针==元素之间的个数,

20.调整奇数偶数顺序

题目:

输入一个整数数组,实现一个函数,

来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,

所有偶数位于数组的后半部分。

这个程序的目标是将一个整数数组重新排序,使得所有的奇数都位于偶数之前。为了实现这个目标,我们采用了双指针的方法。

核心方法:

  1. 双指针法:我们使用两个指针,一个从数组的开始向后移动,一个从数组的结束向前移动。这两个指针分别用于找到偶数和奇数,并在找到之后进行交换。

  2. 前向后找偶数:我们从数组的开始向后扫描,当遇到第一个偶数时停止。这是通过一个循环实现的,只要当前元素是奇数,就将前指针向后移动。

  3. 后向前找奇数:我们从数组的结束向前扫描,当遇到第一个奇数时停止。这同样是通过一个循环实现的,只要当前元素是偶数,就将后指针向前移动。

  4. 交换元素:当我们找到一对偶数和奇数时,我们就交换他们。这是通过创建一个临时变量来实现的,用它来保存偶数的值,然后将奇数的值赋给偶数,最后将临时变量的值赋给奇数。

  5. 循环直至两指针相遇:我们将上述过程放在一个大循环中,只要前指针仍然在后指针之前,就继续这个过程。当两个指针相遇时,说明所有的奇数都已经在偶数之前了,我们就完成了任务。

void move_jo(int* arr,int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		//从左往右找偶数,找到就停下
		while (left < right && arr[left] % 2 == 1)
		{
			left++;
		}
		//从右往左找奇数,找到就停下
		while (left < right && arr[right] % 2 == 0)
		{
			right--;
		}
		//交换
		if (left < right)
		{
			int tep = arr[left];
			arr[left] = arr[right];
			arr[right] = tep;
			left++;
			right--;
		}
	}
}
int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);

	for (int i = 0; i < sz; i++)
	{
		scanf("%d", &arr[i]);
	 }
	move_jo(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

	return 0;
}

//调整奇数偶数顺序
/*
思路:
1. 给定两个下标left和right,left放在数组的起始位置,right放在数组中最后一个元素的位置
2. 循环进行一下操作
 a. 如果left和right表示的区间[left, right]有效,进行b,否则结束循环
 b. left从前往后找,找到一个偶数后停止
 c. right从后往前找,找到一个奇数后停止
 d. 如果left和right都找到了对应的数据,则交换,继续a,
 */
void jo_move(int arr[], int sz)
{
	int left = 0;
	int right = sz - 1;
	while (left < right)
	{
		// 从前往后,找到一个偶数,找到后停止
		while (arr[left] % 2 != 0 && left<right)//先找偶数
		{
			left++;
		}
		// 从后往前找,找一个奇数,找到后停止
		while (arr[right] % 2 == 0 && left < right)//先找奇数
		{
			right--;
		}
		//交换
		// 如果偶数和奇数都找到,交换这两个数据的位置
	 // 然后继续找,直到两个指针相遇
		if (left < right)
		{
			int tep = arr[left];
			arr[left] = arr[right];
			arr[right] = tep;
		}
	}
}
int main()
{
	int arr[] = { 1,2,3,4,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	jo_move(arr, sz);
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
   }

}

21.求天数

/求出当前月份之前的所有月份天数
//判断二月否是闰年--29  不是 -28
//计算1-12月份的天数以及输入的天数之和

int main()
{
	int arr[] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
	int month = 0;
	int year = 0;
	int day = 0;
	int day_count = 0;

	scanf("%d %d %d", &year, &month, &day);
	//
	if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
	{
		arr[2] = 29;
	}
	//
	//计算该日是这一年的第几天
	for (int i = 0; i < month; i++)
	{
		day_count += arr[i];
	}
	day_count += day;
	printf("%d 年 %d 月 %d 日是这一年的第 %d 天。\n", year, month, day, day_count);

	return 0;
	         
}

这段代码的核心方法可以总结为:

  1. 首先定义了一个数组 arr 存储了每个月的天数,其中下标 0 不用,1-12 分别代表了 1 月到 12 月的天数。
  2. 接收用户输入的年、月、日,并判断是否闰年来更新二月的天数。
  3. 使用循环遍历到输入的月份之前,累加每个月的天数,以计算出输入日期是当年的第几天。
  4. 输出结果,显示输入的年、月、日是当年的第几天。

这段代码主要实现了根据用户输入的日期计算该日期在当年中是第几天的功能。

22 杨氏矩阵

//有一个数字矩阵,矩阵的每行从左到右是递增的,
//矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。
//1 2 3
//4 5 6
//7 8 9

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

//有一个数字矩阵,矩阵的每行从左到右是递增的,
//矩阵从上到下是递增的,请编写程序在这样的矩阵中查找某个数字是否存在。
//1 2 3
//4 5 6
//7 8 9
//int Find_num(int arr[3][3], int r, int c, int k)
//{
//	int x = 0;//行下标         右上角  拿右上角的元素和你要找的元素进行比较即可
//	int y = c - 1;//列下标 
//	while(x<=r-1 && y>=0)
//	{ 
//		if (k < arr[x][y])
//		{
//			y--;//最后一列就不找了
//		}
//		else if (k > arr[x][y])
//		{
//			x++;//第一行就不找了
//		}
//		else
//		{
//			return 1;
//		}
//	}
//	return 0; //找不到了
//
//}
//int main()
//{
//	int k = 0;
//	int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
//	scanf("%d", &k);//要找的数字
//	int ret=Find_num(arr, 3, 3, k);
//	printf("%d\n", ret);
//	return 0;
//}


//struct Point
//{
//	int x;
//	int y;
//};
//
//struct Point Find_num(int arr[3][3], int r, int c, int k)
//{
//	int x = 0;//行下标         右上角  拿右上角的元素和你要找的元素进行比较即可
//	int y = c - 1;//列下标 
//	struct Point p = { -1,-1 };
//	while (x <= r - 1 && y >= 0)
//	{
//		if (k < arr[x][y])
//		{
//			y--;//最后一列就不找了
//		}
//		else if (k > arr[x][y])
//		{
//			x++;//第一行就不找了
//		}
//		else
//		{
//			p.x = x;//将计算得x赋给结构体变量里的成员
//			p.y = y;//将计算得y赋给结构体变量里的成员
//			return p;
//		}
//	}
//	return p; //找不到了
//
//}
//int main()
//{
//	int k = 0;
//	int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
//	while (~scanf("%d", &k))//要找的数字)
//	{
//	
//		struct Point ret = Find_num(arr, 3, 3, k);
//		printf("%d %d\n", ret.x,ret.y);
//	}
//	return 0;
//}



int Find_num(int arr[3][3], int *px, int *py, int k)
{
	int x = 0;//行下标         右上角  拿右上角的元素和你要找的元素进行比较即可
	int y = *py- 1;//列下标 
	while(x<=*px-1 && y>=0)
	{ 
		if (k < arr[x][y])
		{
			y--;//最后一列就不找了
		}
		else if (k > arr[x][y])
		{
			x++;//第一行就不找了
		}
		else
		{
			*px = x;
			*py = y;
			return 1;
		}
	}
	*px = -1;
	*py = -1;
	return 0; //找不到了

}
int main()
{
	int k = 0;
	int arr[3][3] = { 1,2,3,4,5,6,7,8,9 };
	while (~scanf("%d", &k))//要找的数字)
	{
		int x = 3;//3行
		int y = 3;//3列
		int ret = Find_num(arr, &x, &y, k);
		if (ret == 1)
		{
			printf("%d %d\n", x, y);
	    }
		else
		{
			printf("找不到\n");
		}
	}
	return 0;
}

总结:

通过右下标的特殊位置来和你输入的数进行比较,小于你输入的数就使列--一下,如果大于就使行++一下 ,他们的前提是 行小于总行号,列大于=0的其他条件

23.求三角形面积公式

#include<stdio.h>	//标准输入输出头文件
#include<math.h>	//需用数学公式sqrt【平方根计算】
void main()
{
	float a,b,c,p;	//边长和面积可为小数
	double S;
	printf("请输入三边长度:\n");	//每次输入以Enter键结束
	scanf("%f %f %f", &a,&b,&c);	//输入变量
	if(a+b>c && b+c>a && a+c>b)		//判断任意两边之和是否大于第三边
	{
		p=(a+b+c)/2;
		S=sqrt(p*(p-a)*(p-b)*(p-c));	//sqrt开平方,计算面积
		printf("此三角形面积为:%7.2f\n",S);		//宽度为7,其中.2表示小数点后保留2位
	}
	else
	{
		printf("您输入的三边不构成三角形!\n");
	}
}

24.字符串旋转结果

写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。

例如:给定s1 =AABCD和s2 = BCDAA,返回1

给定s1=abcd和s2=ACBD,返回0.

AABCD左旋一个字符得到ABCDA

AABCD左旋两个字符得到BCDAA

AABCD右旋一个字符得到DAABC

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//写一个函数,判断一个字符串是否为另外一个字符串旋转之后的字符串。
//例如:给定s1 = AABCD和s2 = BCDAA,返回1
//给定s1 = abcd和s2 = ACBD,返回0.
//AABCD左旋一个字符得到ABCDA
//AABCD左旋两个字符得到BCDAA
//AABCD右旋一个字符得到DAABC
方法1
//int is_move(char arr1[], char arr2[])
//{
//	int len = strlen(arr1);
//	for (int i = 0; i < len; i++)
//	{
//		int tep = arr1[0];
//		for (int j = 0; j < len - 1; j++)
//		{
//			arr1[j] = arr1[j + 1];
//             
//		}
//		arr1[len - 1] = tep;
//		if (strcmp(arr1, arr2) == 0)
//		{
//			return 1;
//		}
//
//	}
//	return 0;
//}
//方法2
#include <string.h>
int is_move(char arr1[], char arr2[])
{
	int len1= strlen(arr1);
	int len2 =strlen(arr2);
	if (len1 != len2)
		return 0;

	strncat(arr1, arr1, len1);
	char* ret = strstr(arr1, arr2);
	if (ret == NULL)
		return 0;
	else
		return 1;


}
int main()
{
	char arr1[40] = "abcdef";
	char arr2[] =   "bcdefa";
	//abcdefabcdef
	//bcdefa
	//cdefab
	//defabc
	//efabcd
	//fabcde
	//abcdef
	//这些字串包含在arr1里面

	int ret=is_move(arr1, arr2);
	if (ret == 1)
	{
		printf("是的\n");
	}
	else
	{
		printf("不是\n");
	}

	return 0;
}

这题巧妙的运用了strncat(字符串连接函数)因为可以在字符串里面可以找到字串
然后再通过查找字串函数来找到字串来达到效果


需要注意的是  arr1 arr2 长度要一样否则就找不到字串

25.单身狗问题

/一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
//编写一个函数找出这两个只出现一次的数字。
//有数组的元素是:1,2,3,4,5,1,2,3,4,6
//只有5和6只出现1次,要找出5和6.

// Step 1: 对数组中所有数字进行异或操作
// Step 2: 找出结果中为1的最右边的一位
// Step 3: 根据最右边的一位将原数组分成两组,并分别进行异或操作
void find_single_dog(int arr[], int sz)
{
	int ret = 0;
	for (int i = 0; i < sz; i++)
	{
		// Step 1: 对数组中所有数字进行异或操作
		ret ^= arr[i];//最终得出来就是二个单身狗异或的结果  --- 5^6
	}
	// Step 2: 找出结果中为1的最右边的一位
	int num = 0;
	num = ret & -ret;//一个数按位与上一个本身取反的数  ---效果就是得出结果为1的最右边
	//比如 6  110 
	//6的补码表示为001(取反加一)---010,
	//按位与 010  就可以得出1的最右边的一位了。
	int x = 0;
	int y = 0;
	for (int i= 0; i < sz; i++)
	{
		//根据最右边的一位将原数组分成两组,并分别进行异或操作
		if (arr[i] & num==1)
		{
			x ^= arr[i];		
		}	
		else
		{
			y ^= arr[i];
		}
	
	}
	printf("dog1=%d dog2=%d\n", x, y);
}
int main()
{
	int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	find_single_dog(arr, sz);
	return 0;
}
//一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
//编写一个函数找出这两个只出现一次的数字。
//有数组的元素是:1,2,3,4,5,1,2,3,4,6
//只有5和6只出现1次,要找出5和6.
void fin_signle_dog(int arr[], int sz, int* pd1, int* pd2)
{
	int ret = 0;
	//异或
	for (int i = 0; i < sz; i++)
	{
		ret ^= arr[i];
	}
	//计算ret的二进制中最右的为1是第几位
	int pos = 0;
	for ( pos = 0; pos < 32;  pos++)
	{
		if (((ret >> pos) & 1) == 1)
		{
			break;//选择pos已经知道ret的二进制在哪一位有1  n
		}
	}
	for (int i= 0; i < sz; i++)
	{
		if ((( arr[i] >>pos ) & 1) == 1)
		{
			
			*pd1 ^= arr[i];//最后把分组好的数在按位与得出单身狗1
		}
		else

			*pd2 ^= arr[i];


	}
}
//核心思想
//找出所有数字异或
//找出异或的数字中哪一位为 1-----n
//以第n为1分一组,以第n位为0分一组
//最后每一组异或就是每一组的单身狗
int main()
{
	// 5^6
	//101 5-B 1 1 3 3
	//110 6-A 2 2 4 4
	//011
	int arr[] = { 1,2,3,4,5,1,2,3,4,6 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	int dog1 = 0;
	int dog2 = 0;
	fin_signle_dog(arr, sz, &dog1, &dog2);
	printf("%d %d\n", dog1, dog2);
	return 0;
}

//核心思想
//找出所有数字异或
//找出异或的数字中哪一位为 1-----n
//以第n为1分一组,以第n位为0分一组
//最后每一组异或就是每一组的单身狗

    // 5^6
    //101 5-B 1 1 3 3
    //110 6-A 2 2 4 4
    //011

求0+2+4+.8+16......n的和
#include <stdio.h>
#include <math.h>


int main()
{
    int sum = 0;
    int n = 0;
    scanf("%d", &n);
    for (int i = 0; i < n; i++)
    {
        int ret = (1 << i);
        sum += ret;
    }
    printf("%d\n", sum-1);
    return 0;
}

26.一串字符每个字母出现的次数

这段代码的目的是统计输入字符串中每个字母(不区分大小写)出现的次数。

  1. 变量定义:

    • str[100]: 用于存储用户输入的字符串,最多可以存储99个字符和一个终止字符\0
    • count[26]: 用于统计26个英文字母出现的次数,数组的大小是26,对应于26个英文字母。
  2. 输入获取:

    • 使用fgets函数从标准输入(通常是键盘)读取字符串并存储在str数组中。
  3. 字母计数:

    • 通过循环遍历输入的每个字符。
    • 如果字符是小写字母(在'a''z'之间),则增加对应索引的计数。
    • 如果字符是大写字母(在'A''Z'之间),同样增加对应索引的计数。
  4. 结果输出:

    • 再次循环遍历26个字母的计数数组。
    • 如果某个字母的计数大于0,则输出该字母及其出现的次数。

总结方法:

  1. 使用一个大小为26的计数数组来记录每个字母出现的次数。
  2. 判断输入的字符是否为字母,并根据其大小写调整索引值。
  3. 遍历输入字符串并使用fgets函数获取输入。
  4. 使用条件语句检查字符是否为小写或大写字母,并相应地增加计数。
  5. 输出出现次数大于0的字母及其次数。

一串字符每个字母出现的次数
#include <stdio.h>  

int main()
{
	char str[100] = { 0 };
	int count[26] = { 0 };
	fgets(str, sizeof(str), stdin);
	for (int i = 0; str[i] != '\0'; i++)
	{
		if (str[i] >= 'a' && str[i] <= 'z')
		{
			count[str[i] - 'a']++;
		}
		else if(str[i] >= 'A' && str[i] <= 'Z')
		{
			count[str[i] - 'A']++;
		}
	}
	for (int i = 0; i < 26; i++)
	{
		if(count[i]>0)
		printf("%c:%d\n", 'a' + i, count[i]);
	}
	return 0;
}

#include <stdio.h>

int main() {
  
  int arr[51]={0};
   int n=0;
   scanf("%d",&n);
   for(int i=0;i<n;i++)
   {
    scanf("%d",&arr[i]);
   }
   int m=0;
   scanf("%d",&m);
   int j=0;
   for( j=n-1;j>=0;j--)
   {
    if(arr[j]>m)
    {
        arr[j+1]=arr[j];
    }
    else {
    arr[j+1]=m;
    break;
    }
   }
   if(j<0)
   {
    arr[0]=m;
   }
   for(int i=0;i<=n;i++)
   {
    printf("%d ",arr[i]);
   }
   printf("\n");

    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值