【C语言初阶(14)】扫雷游戏(优化:标记地雷+自动展开)

news2024/11/27 0:32:29

文章目录

  • Ⅰ游戏规则
  • Ⅱ 游戏实现思路
  • Ⅲ 游戏实现步骤
    • ⒈菜单界面
    • ⒉创建棋盘
      • ① 创建两个棋盘
      • ② 防止数组越界
    • ⒊棋盘初始化
    • ⒋棋盘的打印
    • ⒌布置地雷
    • ⒍玩家排查雷实现步骤
    • ⒎计算 x,y 周围有多少雷
    • ⒏展开非雷区
    • ⒐标记地雷
    • ⒑取消标记
  • Ⅳ 模块化代码实现
    • ⒈test.c
    • ⒉game.h
    • ⒊game.c
  • Ⅴ 结果演示

Ⅰ游戏规则

在一个9×9(初级)、16×16(中级)、16×30(高级)或自定义大小的方块矩阵中随机布置一定量的地雷(初级为10个,中级为40个,高级为99个),再由玩家逐个翻开方块,以找出所有地雷为最终游戏目标。如果玩家翻开的方块有地雷,则游戏结束。

游玩方式

  • 点击一个格子,如果这个位置不是地雷,会显示以这个坐标为中心形成的一个九宫格范围内有几个地雷。
  • 例如:你点了一个格子,显示出 1 ,就说明它周围的8的格子里有 1 个雷,是 2 就有两个雷,是 3 就有三个雷···以此类推。
  • 直到玩家未点击的格子数目等于地雷数,则排雷成功,游戏胜利。

在这里插入图片描述

Ⅱ 游戏实现思路

先把过程现在前面,方便后续直接看着这个步骤写出代码

  1. 创建菜单界面函数选择退出游戏或者是进入游戏。
  2. 创建两个二维数组用以存放布置好的雷的信息以及排查出的雷的信息。
  3. 进行棋盘的初始化。
  4. 打印出初始化好后的棋盘。
  5. 给十个地雷分配随机位置。
  6. 输入要排查地雷的坐标。
  7. 检查输入的坐标是不是地雷,字符 ‘1 ’表示该位置是地雷,字符 ‘ 0 ’ 表示该位置不是地雷。
    • 输入坐标的时候一共有 4 种结果:① 被雷炸死、② 输入的坐标重复、③ 输入的坐标范围越界、④ 排雷成功。
  8. 排查玩家输入的作标周围有几个雷。
  9. 最后,再回到步骤 1 ,选择 进入游戏 以及 退出游戏。

Ⅲ 游戏实现步骤

⒈菜单界面

  • 不管玩不玩游戏,都要提供一个菜单以供选择。
void menu()
{
	printf("|-------------------------------|\n");
	printf("|----------MineSweeper----------|\n");
	printf("|*******************************|\n");
	printf("|******   1.play 0.exit   ******|\n");
	printf("|*******************************|\n");
	printf("|是雷为 '1' --------- 非雷为 '0'|\n");
	printf("|-------------------------------|\n");
}

⒉创建棋盘

① 创建两个棋盘

为什么要创建两个棋盘?

  • 我们已经知道,在棋盘中字符 ‘ 1 ’ 表示该处为地雷;
  • 但同样的,如果输入的作标处不是雷,但是它的九宫格范围内有一个雷,该位置也应该显示一个字符 ‘ 1 ’ 来表示它附近有一个雷。
  • 那么问题莱纳,该怎么区分这个位置显示出的 ‘ 1 ’,表示的是雷的 1 还是它附近有一个雷的 1?

在这里插入图片描述

解决方法

  • 创建两个二位数组(棋盘),mine[][] 和 show[][]
  • mine 用来存放雷的位置信息(这个不能展示出来,不然雷在哪都给你瞧见了)。
  • show 用来存放排查出的雷的信息。

② 防止数组越界

  • 现在已经知道了,在输入坐标的时候会检查该作标的范围内的 8 个格子中有几个地雷。
  • 但是如果我输入的坐标在角落上,九宫格范围超过了棋盘范围,阁下该如何应对呢。

在这里插入图片描述

将二维数组扩大一圈

  • 将 9 * 9 棋盘上下左右各扩大一排,变成一个 11 * 11 的棋盘,这样就不会出现数组越界得问题了。
  • 当然,实际使用肯定还是在中间的 9 * 9 的棋盘上进行的。

在这里插入图片描述

扩张棋盘的好处

  1. 防止数组越界
  2. 符合用户习惯:从玩家角度输入坐标 ,刚好就是我们棋盘实际使用的范围。不用再对玩家输入的坐标进行操作了。

棋盘定义

//玩家看到的期盼大小
#define ROW 9 //行
#define COL 9 //列

//棋盘的实际大小
#define ROWS ROW + 2 
#define COLS COL + 2
char mine[ROWS][COLS] = { 0 };		//存放布置好的地雷的信息
char show[ROWS][COLS] = { 0 };		//存放排查出的地雷的信息

⒊棋盘初始化

  • 将 mine 数组全部初始化为字符 ‘ 0 ’;
  • 将 show 数组全部初始化为字符 ‘ * ’。
  • 不在初始化函数设定初始化得值,而是将要初始化得内容作为参数传递给函数,让函数具有通用性。
//初始化棋盘
void init_board(char board[ROWS][COLS], int rows, int cols,char set)
{
	int i = 0;
	int j = 0;

	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
			//board[i][j] = '0';如果这样弄函数就不具备通用性了
		}
	}
}

⒋棋盘的打印

  • 注意:棋盘只打印出 9 * 9 的内容;
  • 并且 mine 棋盘只有在游戏失败/游戏胜利时才会打印出来。
//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;

	printf("\n----MineSweeper----\n");

	//打印列号
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	putchar('\n');

	//显示出的棋盘的行和列都从 1 开始
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//打印行号
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		putchar('\n');
	}

	printf("----MineSweeper----\n");

}

效果展示

在这里插入图片描述

⒌布置地雷

  • 设置 10 个地雷,利用 rand 函数在雷盘上随机分配十个位置;
  • 分配好雷的位置全部改成字符 ‘ 1 ’。

game.h

#define EASY_COUNT 10 //雷的数量

game.c

//布雷
void set_mine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//10

	while (count)					//雷布完之后自然退出循环
	{
		int x = rand() % row + 1;	//1 - 9
		int y = rand() % col + 1;	//1 - 9

		if ('0' == board[x][y])		//该坐标还未布雷
		{
			board[x][y] = '1';
			count--;//这个要放在这里面,不然雷的布置的数量和设置的数量不一致

		}
	}

效果演示

在这里插入图片描述

⒍玩家排查雷实现步骤

  • 检查坐标处是不是雷,布置存放的是字符’1’,没有放置雷存放的是字符’0’。
  • 判断坐标输入合法性几种情况:
    • 很遗憾,你被炸死了!
    • 该位置已被排查过,请重新输入
    • 坐标非法,请重新输入
    • 恭喜你,排雷成功
  • 其中,在游戏胜利以及被雷炸死后会显示出雷区。
//排雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;//找到非雷的个数
	int operate = 0;

	while (win < ROW * COL - EASY_COUNT)//游戏赢了就退出循环
	{
		putchar('\n');
		printf("|------------------|\n");
		printf("|--- 1.排查地雷 ---|\n");
		printf("|--- 2.标记地雷 ---|\n");
		printf("|--- 3.取消标记 ---|\n");
		printf("|------------------|\n");

		printf("  请选择你的操作:");
		scanf("%d", &operate);

		if(1==operate)
		{
			display_board(show, ROW, COL);
			printf("请输入要排查的坐标:");
			scanf("%d %d", &x, &y);
			//判断坐标是否合法
			if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
			{
				if (show[x][y] != '*')
				{
					printf("该位置已被排查过,请重新输入\n");
				}
				if ('1' == mine[x][y])			//如果是雷
				{
					printf("\n很遗憾,你被炸死了\n");
					display_board(mine, ROW, COL);//挂了之后要展示雷的位置
					break;
				}
				else							//如果不是雷,就要统计周围有几个雷
				{
					spreed(mine, show, x, y);	//展开条件1,该坐标不是雷
					display_board(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("坐标非法,请重新输入\n");
			}
		}
		else if (2 == operate)
		{
			mark_mine(show, ROW, COL);
		}
		else if (3 == operate)
		{
			cancel_mark(show, ROW, COL);
		}
	}
	if (ROW * COL - EASY_COUNT == win)
	{
		printf("\n恭喜你,排雷成功\n");
		display_board(mine, ROW, COL);
	}
}

游戏胜利条件

  • 未翻开的格子数等于雷数时,游戏胜利。

⒎计算 x,y 周围有多少雷

排查思路

  • 在存放地雷的数组 mine 内进行排查。
  • 将玩家输入的坐标周围那一圈 8 个位置的字符全部加起来,结果是多少就有多少个雷。
  • 将结果显示到 show 数组去。

但是又有个问题了

  • 我们往地雷数组里面存放的是字符 ‘ 1 ’ 以及字符 ‘ 0 ’,而不是普通的数字 1 和 0。
  • 如果将这些个玩楞加起来,结果肯定不是我们想要的雷的数量。

解决方法

  • 我们将每个方位得到的字符减去一个字符 ‘ 0 ’,就能得到正常的数字了。
    • 例如:‘ 1 ’ - ‘ 0 ’ = 1。
  • 所以,我们 x,y 周围 8 个方位的字符都加起来之后,再减去八个字符 ‘ 0 ’(8 * ‘ 0 ’)就是 x,y 周围雷的数量了。

在这里插入图片描述

//统计x,y周围有几个雷
int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y] +
		board[x - 1][y - 1] +
		board[x][y - 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] +
		board[x][y + 1] +
		board[x - 1][y + 1] - 8 * '0');
}

⒏展开非雷区

  • 当我们在玩扫雷游戏的时候会发现,点击某个区域的时候会展开一大片区域。
  • 这是因为点击的这个作标周围八个格子都没有雷,并且这八个格子每个的展开范围内都有一片区域没有雷。
  • 就这样一层一层的展开之后,最后会展开一大片区域。

在这里插入图片描述

当排查 x,y 坐标时的展开条件

  1. 该坐标不是雷。
  2. 该坐标没有被排查过。
  3. 该坐标周围没有雷(该坐标显示的是 0 )。
  4. 该坐标的周围 8 个坐标是否也满足前两个条件(有没有感觉递归要来了)。

代码实现

//展开非雷区
void spreed(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	int i = 0;
	int j = 0;

	//限制在棋盘内展开,防止越界
	if ((x >= 1 && x <= ROW) && (y >= 1 && y <= COL))
	{
		int count = get_mine_count(mine, x, y);
		
		if (0 == count)//展开条件2,该坐标周围没有雷
		{
			show[x][y] = ' ';//现将该坐标置成空格

			for (i = x - 1; i <= x + 1; i++)
			{
				for (j = y - 1; j <= y + 1; j++)
				{
					if ('*' == show[i][j])//展开条件3,该坐标没有被排查过
					{
						//满足条件,展开递归
						spreed(mine, show, i, j);//将坐标从 x y 向外扩散
						//递归要传过去的新坐标是 i j 别把 x y 传过去了 (恼)
					}
				}
			}
		}
		else//周围有雷,结束展开
		{
			show[x][y] = count + '0';
		}
	}
}

效果演示

在这里插入图片描述

⒐标记地雷

  • 在扫雷游戏过程中,如果我们已经确定了某个位置是地雷,可以对该处进行标记。

在这里插入图片描述

  • 这里我们用 ‘ ! ’ 来作为标记符。
  • 当该位置没有被排查过时(不是 ‘ * ’),才可以将 ‘ ! ’ 赋给 show 数组的这个位置。

代码实现

//标记地雷
void mark_mine(char show[ROWS][COLS],int row, int col)
{
	int x = 0;
	int y = 0;

	display_board(show, ROW, COL);
	printf("请输入要标记的坐标:");
	scanf("%d %d", &x, &y);

	if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
	{
		if ('!' == show[x][y])
		{
			printf("该坐标已被标记,请重新输入\n");
		}
		else if ('*' == show[x][y])
		{
			show[x][y] = '!';
			printf("标记成功\n");
			display_board(show, ROW, COL);
		}
	}
	else
	{
		printf("坐标非法,请重新输入\n");
	}
}

结果演示

在这里插入图片描述

⒑取消标记

  • 在 show 数组中,输入的坐标处如果是 ‘ ! ’,则能够取消坐标,否则重新输入坐标。
//取消标记
void cancel_mark(char show[ROWS][COLS], int row, int col)
{
	int i = 0;
	int x = 0;
	int y = 0;
	int count = 0;

	printf("请输入要取消多少个标记:");
	scanf("%d", &count);

	while(i < count)
	{
		printf("请输入要取消标记的坐标:");
		scanf("%d %d", &x, &y);
		display_board(show, ROW, COL);

		if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
		{
			//取消标记
			if ('!' == show[x][y])
			{
				show[x][y] = '*';
				printf("取消标记成功\n");
				display_board(show, ROW, COL);
				i++;//这玩意放的位置别搞错了
			}
			else if ('*' == show[x][y])
			{
				printf("该坐标未被标记,请重新输入作标\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

Ⅳ 模块化代码实现

⒈test.c

#include "game.h"

void menu()
{
	printf("|-------------------------------|\n");
	printf("|----------MineSweeper----------|\n");
	printf("|*******************************|\n");
	printf("|******   1.play 0.exit   ******|\n");
	printf("|*******************************|\n");
	printf("|是雷为 '1' --------- 非雷为 '0'|\n");
	printf("|-------------------------------|\n");
}


void game()//游戏的整个流程
{
	int  operate = 0;
	char mine[ROWS][COLS] = { 0 };		//存放布置好的地雷的信息
	char show[ROWS][COLS] = { 0 };		//存放排查出的地雷的信息

	init_board(mine, ROWS, COLS, '0');	//mine 数组在没有布雷时,都是 '0'
	init_board(show, ROWS, COLS, '*');	//show 数组在没有排查时,都是 '*'
	set_mine(mine, ROW, COL);			//将雷布置到中间的9*9的格子里去
	display_board(show, ROW, COL);		//只打印中间9*9的内容,不打印外圈
	find_mine(mine, show, ROW, COL);	//排雷
}

int main()
{
	int input = 0;
	srand((unsigned int)time(NULL));	//设置随机数的生成起点

	do
	{
		menu();
		printf("\n请选择是否开始游戏:");
		scanf("%d", &input);

		switch (input)
		{
		case 1:
			printf("\n开始游戏\n"); game(); break;
		case 0:
			printf("\n退出游戏\n"); break;
		default:
			printf("\n输入错误\n"); break;
		}
	} while (input);

	return 0;
}

⒉game.h

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

//玩家看到的棋盘大小
#define ROW 9 //行
#define COL 9 //列

//棋盘的实际大小
#define ROWS ROW + 2 
#define COLS COL + 2

#define EASY_COUNT 10 //雷的数量

//初始化数组为指定的字符
void init_board(char board[ROWS][COLS], int rows, int cols,char set);

//打印棋盘信息
void display_board(char board[ROWS][COLS], int row, int col);

//布雷
void set_mine(char board[ROWS][COLS], int row, int col);

//排雷
void find_mine(char mine[ROWS][COLS],char show[ROWS][COLS],int row, int col);

//标记地雷
void mark_mine(char show[ROWS][COLS], int row, int col);

//取消标记
void cancel_mark(char show[ROWS][COLS], int row, int col);

//展开非雷区
void spreed(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y);

⒊game.c

#include "game.h"

//初始化棋盘
void init_board(char board[ROWS][COLS], int rows, int cols,char set)
{
	int i = 0;
	int j = 0;

	for (i = 0; i < rows; i++)
	{
		for (j = 0; j < cols; j++)
		{
			board[i][j] = set;
			//board[i][j] = '0';如果这样弄函数就不具备通用性了
		}
	}
}

//打印棋盘
void display_board(char board[ROWS][COLS], int row, int col)
{
	int i = 0;
	int j = 0;

	printf("\n----MineSweeper----\n");
	//打印列号
	for (j = 0; j <= col; j++)
	{
		printf("%d ", j);
	}
	putchar('\n');

	//显示出的棋盘的行和列都从 1 开始
	for (i = 1; i <= row; i++)
	{
		printf("%d ", i);//打印行号
		for (j = 1; j <= col; j++)
		{
			printf("%c ", board[i][j]);
		}
		putchar('\n');
	}
	printf("----MineSweeper----\n");
}

//布雷
void set_mine(char board[ROWS][COLS], int row, int col)
{
	int count = EASY_COUNT;//10

	while (count)					//雷布完之后自然退出循环
	{
		int x = rand() % row + 1;	//1 - 9
		int y = rand() % col + 1;	//1 - 9

		if ('0' == board[x][y])		//该坐标还未布雷
		{
			board[x][y] = '1';
			count--;//这个要放在这里面,不然雷的布置的数量和设置的数量不一致

		}
	}
}

//统计x,y周围有几个雷
int get_mine_count(char board[ROWS][COLS], int x, int y)
{
	return (board[x - 1][y] +
		board[x - 1][y - 1] +
		board[x][y - 1] +
		board[x + 1][y - 1] +
		board[x + 1][y] +
		board[x + 1][y + 1] +
		board[x][y + 1] +
		board[x - 1][y + 1] - 8 * '0');
}

//排雷
void find_mine(char mine[ROWS][COLS], char show[ROWS][COLS], int row, int col)
{
	int x = 0;
	int y = 0;
	int win = 0;//找到非雷的个数
	int operate = 0;

	while (win < ROW * COL - EASY_COUNT)
	{
		putchar('\n');
		printf("|------------------|\n");
		printf("|--- 1.排查地雷 ---|\n");
		printf("|--- 2.标记地雷 ---|\n");
		printf("|--- 3.取消标记 ---|\n");
		printf("|------------------|\n");

		printf("  请选择你的操作:");
		scanf("%d", &operate);

		if(1==operate)
		{
			display_board(show, ROW, COL);
			printf("请输入要排查的坐标:");
			scanf("%d %d", &x, &y);
			//判断坐标是否合法
			if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
			{
				if (show[x][y] != '*')
				{
					printf("该位置已被排查过,请重新输入\n");
				}
				if ('1' == mine[x][y])			//如果是雷
				{
					printf("\n很遗憾,你被炸死了\n");
					display_board(mine, ROW, COL);//挂了之后要展示雷的位置
					break;
				}
				else							//如果不是雷,就要统计周围有几个雷
				{
					//int count = get_mine_count(mine, x, y);
					//show[x][y] = count + '0';
					spreed(mine, show, x, y);	//该坐标不是雷
					display_board(show, ROW, COL);
					win++;
				}
			}
			else
			{
				printf("坐标非法,请重新输入\n");
			}
		}
		else if (2 == operate)
		{
			mark_mine(show, ROW, COL);
		}
		else if (3 == operate)
		{
			cancel_mark(show, ROW, COL);
		}
	}
	if (ROW * COL - EASY_COUNT == win)
	{
		printf("\n恭喜你,排雷成功\n");
		display_board(mine, ROW, COL);
	}
}

//标记地雷
void mark_mine(char show[ROWS][COLS],int row, int col)
{
	int x = 0;
	int y = 0;

	display_board(show, ROW, COL);
	printf("请输入要标记的坐标:");
	scanf("%d %d", &x, &y);

	if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
	{
		if ('!' == show[x][y])
		{
			printf("该坐标已被标记,请重新输入\n");
		}
		else if ('*' == show[x][y])
		{
			show[x][y] = '!';
			printf("标记成功\n");
			display_board(show, ROW, COL);
		}
	}
	else
	{
		printf("坐标非法,请重新输入\n");
	}
}

//取消标记
void cancel_mark(char show[ROWS][COLS], int row, int col)
{
	int i = 0;
	int x = 0;
	int y = 0;
	int count = 0;

	printf("请输入要取消多少个标记:");
	scanf("%d", &count);

	while(i < count)
	{
		printf("请输入要取消标记的坐标:");
		scanf("%d %d", &x, &y);
		display_board(show, ROW, COL);

		if ((x >= 1 && x <= row) && (y >= 1 && y <= col))
		{
			//取消标记
			if ('!' == show[x][y])
			{
				show[x][y] = '*';
				printf("取消标记成功\n");
				display_board(show, ROW, COL);
				i++;
			}
			else if ('*' == show[x][y])
			{
				printf("该坐标未被标记,请重新输入作标\n");
			}
		}
		else
		{
			printf("坐标非法,请重新输入\n");
		}
	}
}

//展开非雷区
void spreed(char mine[ROWS][COLS], char show[ROWS][COLS], int x, int y)
{
	int i = 0;
	int j = 0;

	//限制在棋盘内展开,防止越界
	if ((x >= 1 && x <= ROW) && (y >= 1 && y <= COL))
	{
		int count = get_mine_count(mine, x, y);
		if (0 == count)								//该坐标周围没有雷
		{
			show[x][y] = ' ';

			for (i = x - 1; i <= x + 1; i++)
			{
				for (j = y - 1; j <= y + 1; j++)
				{
					if ('*' == show[i][j])			//该坐标没有被排查过
					{
						spreed(mine, show, i, j);	//将坐标从 x y 向外扩散
						//递归要传过去的新坐标是 i j 别把 x y 传过去了 (恼)
					}
				}
			}
		}
		else										//周围有雷,结束展开
		{
			show[x][y] = count + '0';
		}
	}
}

Ⅴ 结果演示

被雷炸死

在这里插入图片描述

游戏胜利

  • 这里为了提升效率,我们把雷的数量弄到 80 个并先展示雷区。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/753420.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

TCP协议下的三大协议的验证实验

系列文章目录 数通王国历险记&#xff08;1&#xff09; 前言 一&#xff0c;我们要先知道PDU是什么&#xff1f; 二、TCP协议下的三大协议的验证实验 1.FTP的验证实验 1&#xff0c;拓扑图 2.将lsw4配置一下 3&#xff0c;FTP服务器端开启FTP服务&#xff1a; 4&#x…

Jenkins的几种安装方式以及邮件配置

目录 Jenkins介绍 Jenkins下载、安装 一、通过war包安装 二、通过docker安装 jenkins 容器中添加 git, maven 等组件 jenkins 容器中的公钥私钥 在 jenkins 容器中调用 docker 简单的方式启动 Docker server REST API 一个 jenkins 示例 三、通过Homebrew安装 访问Je…

静态库 的制作与使用

文章目录 重要命令程序组成静态库制作流程静态库的使用 gcc main.c -o APP -I(i) 头文件路径 -l(L) 库名字&#xff08;xxx) -L 库路径 重要命令 gcc -o -I(大写i) -l(小写L) -L cp&#xff1a;复制文件 -r 递归&#xff0c;用于复制文件夹所有文件 mv&#xff1a;移动文件 程…

代码随想录算法训练营第53天 | 动态规划 part14 ● 1143.最长公共子序列 ●1035.不相交的线 ● 53. 最大子序和

# 1143.最长公共子序列 和718最长公共子数组 对比 本题可以不连续 int longestCommonSubsequence(string text1, string text2) {vector<vector<int>> dp(text1.size() 1, vector<int>(text2.size() 1, 0));for (int i 1; i < text1.size(); i) {for…

陆地生态系统植被净初级生产力(NPP)—CASA模型

由于全球变暖、大气中温室气体浓度逐年增加等问题的出现&#xff0c;“双碳”行动特别是碳中和已经在世界范围形成广泛影响。碳中和可以从碳排放&#xff08;碳源&#xff09;和碳固定&#xff08;碳汇&#xff09;这两个侧面来理解。陆地生态系统在全球碳循环过程中有着重要作…

Swagger、knife4j简介

Swagger 简介 Swagger 是一个规范和完整的框架&#xff0c;用于生成、描述、调用和可视化 RESTful 风格的 Web 服务(API Documentation & Design Tools for Teams | Swagger)。 它的主要作用是&#xff1a; 使得前后端分离开发更加方便&#xff0c;有利于团队协作 接口的…

leetcode 1218. Longest Arithmetic Subsequence of Given Difference(给定差值的最长算术子序列)

给数组arr和一个差值difference, 不打乱arr中数字的顺序&#xff0c;抽取最长的子序列&#xff0c;使序列中每相邻两个元素的差值为difference. 求满足条件的最长子序列的长度。 思路&#xff1a; DP 因为差值difference是固定的&#xff0c;每抽取一个元素&#xff0c;它前…

帆软报表分页预览如何增加一种新的导出类型。

如图,这里要在 导出下拉菜单中新增一个签章PDF的导出。 通过分析源码,发现这个菜单的定义是再报表预览加载的html页面里面 咋们如何再这里面插入我们新加的菜单项呢。 首先该页面的内容是通过MemXPageActor的flushHtml方法产生的。所以我们需要继承MemXPageActor来重载flus…

ios h5底部安全区适配

相信在ios 移动端开发h5前端童鞋 肯定会知道 就是 很多ios款型的手机 底部有一条黑色的杠杠 或者白色哎 就是会遮挡一部分我们的元素 特别是底部需要悬浮一些按钮的时候 这个就是ios的底部安全区域 对应的还有顶部的哈 这里就说下 底部的 <meta name"viewport"…

在Linux中使用curl访问EasyCVR页面,返回报错Unauthorized是什么原因?

EasyCVR可拓展性强、视频能力灵活、部署轻快&#xff0c;可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持厂家私有协议与SDK接入&#xff0c;包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力&#xff0c;比如&#xff1a;视…

第四章 数学知识(四)——容斥原理与博弈论

文章目录 容斥原理博弈论SG函数 容斥原理练习题890. 能被整除的数 博弈论练习题891. Nim游戏893. 集合-Nim游戏892. 台阶-Nim游戏894. 拆分-Nim游戏 容斥原理 若干个相交集合&#xff0c;它们的并集中存在多少个元素&#xff1f; 假设n为所有集合的元素个数相加&#xff0c;因…

vue img 图片损坏时展示替图片

场景&#xff1a;图片地址找不到时&#xff0c;会展示如图一&#xff1b;虽然没什么大影响&#xff0c;但是有点丑&#xff0c;需求是想在图片损坏时展示替补图片&#xff0c;如图二。 代码实现&#xff1a;给img标签加error事件 <img :src"item.imageUrl" :alt&q…

android JSBridge的加载时机问题

https://github.com/lzyzsd/JsBridge 也算是比较悠久和使用了。 可供参考的android和IOS&#xff0c;以及前端的使用 https://segmentfault.com/a/1190000018208609 遇到的问题&#xff1a; 比如&#xff1a; 从前端在加载WebView的时候&#xff0c;执行了某些动作&#xff0c…

【Java/大数据】Kafka简介

Kafka简介 Kafka概念关键功能应用场景 Kafka的原理Kafka 的消息模型早期的队列模型发布-订阅模型Producer、Consumer、Broker、Topic、PartitionPartitionoffsetISR Consumer Groupleader选举Controller leaderPartition leader producer 的写入流程 多副本机制replicas的同步时…

介绍AI绘画课,让智能工具助力创作 释放无限想象力 助你成为绘画大师

演示地址&#xff1a; www.runruncode.com/portal/article/index/id/19458/cid/81.html 画画是一项有趣的活动&#xff0c;它让人充满无限可能。对许多人来说&#xff0c;画画既是一种放松的方式&#xff0c;也是一种与创意、文化和艺术联系的途径。如果你是一个初学者&#x…

《深度学习推荐系统》笔记

目录 一、推荐系统是什么1.作用和意义2.推荐系统的架构2.1 逻辑架构2.2 技术架构 二、传统的推荐系统方法1. 协同过滤算法1.1 userCF&&ItemCF1.3 矩阵分解算法 2. 逻辑回归算法3. 因子分解机3.1 POLY2模型3.2 FM模型3.3 FFM模型3.4 小结 4. 组合模型4.1 GBDTLR组合模型…

valle代码过程

github代码链接 https://github.com/lifeiteng/vall-e/tree/main1.PyTorch pytorch官网 https://pytorch.org/指令 conda install pytorch torchvision torchaudio pytorch-cuda11.8 -c pytorch -c nvidiapip install torchmetrics0.11.12.fbank pip install librosa0.8.1…

前端vue入门(纯代码)33_缓存路由组件

如果我一贫如洗&#xff0c;你将会是我最后一件行李。 【31.Vue Router--缓存路由组件】 背景&#xff1a;在Cartoon组件的input框&#xff0c;输入了一些数据的时候&#xff0c;但是&#xff0c;当我切换到Stars组件的时候&#xff0c;那么Cartoon组件就会被销毁&#xff0c…

易基因“多区域DNA甲基化检测探针设计及其检测方法”获专利授权!

大家好&#xff0c;这里是专注表观组学十余年领跑多组学科研服务的易基因。 DNA甲基化是表观遗传学研究中&#xff0c;修饰最为稳定&#xff0c;含量最为丰富&#xff0c;对基因调控最为活跃、途径最为广泛的一种修饰。不同基因区域或位点的修饰与胚胎发育、疾病发生和发展密切…

三层架构详解

什么是三层架构&#xff1f; 三层架构就是为了符合“高内聚&#xff0c;低耦合”思想&#xff0c;是一种十分完善的软件应用程序架构&#xff0c;它将应用程序组织成三个逻辑和物理计算层&#xff1a;表示层&#xff08;或用户界面&#xff09;、应用层&#xff08;负责处理数据…