图的搜索算法---8.2 ZOJ1002-Fire Net--合理布置碉堡

news2024/9/29 9:32:00

目录

问题:

分析:

 主要的算法代码:

完整代码: 

出问题的代码:

原因:

正确代码:

 

代码分析:

算法函数讲解: 

 CanPut函数

solve函数

运行结果:


问题:

¢ 假设我们有一个方形的城市,其街道都是直的。在方形地图上,有 n 行和 n 列,每个代表一条街道或一堵墙。每个碉堡有 4个射击孔,分别正对东西南北方向。在每个射击孔配备一架高射机枪。
¢ 我们假设,子弹是如此强大,它的射程可以任意远,并能摧毁它所击中的碉堡。墙也是很坚固的,足以阻止子弹的摧毁。
¢ 问题的目标是,在该城市中布置尽可能多的碉堡,而碉堡之间又不会相互摧毁。合理布置碉堡的原则是,没有两个碉堡在同一个水平方向或垂直方向,除非它们之间有墙相隔。在本题中,假定城市很小(最多 4 × 4),而且有子弹不能贯穿的墙壁。

 

输入样例

输出样例

4

.X..

....

XX..

....

5

分析:

¢ 由于 题目规模 很小( n 4 ),采用深度优先 算法 即可

1)数据定义,读取数据

char cMap[5][5];  //地图

int iBest//最优解

int n;  //地图的大小

¢ 数据读取:

while(scanf("%d", &n) && n)

  for(int i = 0; i < n; i++)

        cin>>cMap[i];

  ……

}

 2)判断每个单元格能否放置碉堡

¢ 变量 k 表示单元格的序号,左上角为 0 ,然后从左到右, 从上到下。
l k 16 n 2 时,就表示计算结束。
¢ 变量 current 表示在 当前 布置下,所获得的能够合法布置碉堡的最大值。
¢ 对每一个单元格,可以放置碉堡(假定是合法的),也可以不放置碉堡,因此就有很多种方案。
l 对所有方案, current 的最大 iBest ,就是本题的答案。
l 显然 n很大时,这种搜索方法是很耗时的。

/

0

1

2

3

0

0

1

2

3

1

4

5

6

7

2

8

9

10

11

3

12

13

14

15

 主要的算法代码:

/*
    算法8.1(1) 放置碉堡的深度优先搜索算法
*/
//回溯算法,子集树
void solve(int k, int current)
{  
  int x, y;
  if(k == n*n)   //整个地图判断完毕
  {  //更新最优解
    if(current > iBest)
    {iBest = current; return;}
  }
  else
  { //将单元数转换为xy坐标
    x = k / n;
    y = k % n;
    if(cMap[x][y] == ‘.’  &&  CanPut(x, y))	//左子树
    {
      cMap[x][y] = 'O';   	//放置一个碉堡
      solve(k + 1, current + 1);
      cMap[x][y] = ‘.’; 		//恢复现场
    }
    solve(k + 1, current); 		//不放置碉堡,右子树
  }
}

/*
    算法8.1(2)判断在行row和列col处能否配置碉堡
*/

bool CanPut(int row,  int col)
{  
  int i;
  //判断col列上的合法性
  for(i = row - 1; i >= 0; i--)
  {
    if(cMap[i][col] == 'O') return false;
    if(cMap[i][col] == 'X') break;
  }
  //判断row行上的合法性
  for(i = col - 1; i >= 0; i--)
  {
    if(cMap[row][i] == 'O') return false;
    if(cMap[row][i] == 'X') break;
  }
  return true;
}

该算法使用深度优先搜索(DFS)的思想,从地图的左上角开始,尝试在每个单元格中放置碉堡或者不放置碉堡,直到整个地图都被覆盖。在 DFS 的过程中,我们通过 CanPut 函数来判断当前位置能否放置碉堡,通过 solve 函数进行递归搜索,最后更新最优解并输出。 

完整代码: 

出问题的代码:

  • 无论输入什么,结果都为0.
/*
*	假设我们有一个方形的城市,其街道都是直的。在方形地图上,
	有n行和n列,每个代表一条街道或一堵墙。每个碉堡有4个射击孔,
	分别正对东西南北方向。在每个射击孔配备一架高射机枪。
	我们假设,子弹是如此强大,它的射程可以任意远,并能摧毁它所击中的碉堡。
	墙也是很坚固的,足以阻止子弹的摧毁。
	问题的目标是,在该城市中布置尽可能多的碉堡,而碉堡之间又不会相互摧毁。
	合理布置碉堡的原则是,没有两个碉堡在同一个水平方向或垂直方向,
	除非它们之间有墙相隔。在本题中,假定城市很小(最多4×4),而且有子弹不能贯穿的墙壁。
*/
#include<iostream>
using namespace std;

char cMap[5][5];	//地图
int iBest;		   //最优解
int n;			  //地图大小

//判断在行row和列col处能否配置碉堡
bool CanPut(int row, int col) {
	int i;

	//判断col列上的合法性
	for(i = row - 1; i >= 0; i++) {
		if (cMap[i][col] == 'O')
			return false;
		if (cMap[i][col] == 'X')
			break;
	}
	//判断row行上的合法性
	for (i = col - 1; i >= 0; i--) {
		if (cMap[row][i] == 'O')
			return false;
		if (cMap[row][i] == 'X')
			break;
	}
	return true;
}

//放置碉堡的深度优先搜索算法
void solve(int k,int current) {
	int x, y;

	//整个地图判断完毕
	if (k = n * n) {
		if (current > iBest) {
			iBest = current;
			return;
		}
	}
	else{
		//将单元数转换为xy坐标
		x = k / n;//行
		y = k % n;//列

		//左子树
		if (cMap[x][y] == '.' && CanPut(x, y)) {
			
			//放置一个碉堡
			cMap[x][y] = 'O';
			solve(k + 1, current + 1);

			//恢复现场
			cMap[x][y] = '.';
		}
		solve(k + 1, current);//不放置碉堡,右子树
	}
}

int main() {
	while (cin >> n && n) {
		for (int i = 0; i < n; i++) {
			cin >> cMap[i];
		}
		iBest = 0;//初始化最优解为0
		solve(0, 0);//从第一个单元格开始搜索
		cout << iBest << "\t";//输出最优解
		cout << endl;
	}
	return 0;
}

原因:

这个代码存在一些问题:

  1. 在 CanPut 函数中,第 5 行的循环条件错误,应该是 i >= 0 而不是 i++,否则会导致死循环。
  2. 在 solve 函数中,第 17 行的判断条件使用了赋值符号 =,应该改为相等性判断符号 ==
  3. 在 solve 函数中,没有对地图进行 DFS 搜索时需要恢复现场,即放置/撤回碉堡,否则会影响后续的搜索结果。在放置碉堡后递归搜索后,需要在返回时立即撤回放置的碉堡,恢复现场,使得程序能够正确地搜索到剩余的节点。

修改后的代码如下所示:

//判断在行row和列col处能否配置碉堡
bool CanPut(int row, int col) {
    int i;

    //判断col列上的合法性
    for(i = row - 1; i >= 0; i--) {
        if (cMap[i][col] == 'O')
            return false;
        if (cMap[i][col] == 'X')
            break;
    }
    //判断row行上的合法性
    for (i = col - 1; i >= 0; i--) {
        if (cMap[row][i] == 'O')
            return false;
        if (cMap[row][i] == 'X')
            break;
    }
    return true;
}

//放置碉堡的深度优先搜索算法
void solve(int k,int current) {
    int x, y;

    //整个地图判断完毕
    if (k == n * n) {
        if (current > iBest) {
            iBest = current;
        }
        return;  // 返回时需要恢复现场,即撤回放置的碉堡
    }
    else{
        //将单元数转换为xy坐标
        x = k / n;//行
        y = k % n;//列

        //左子树
        if (cMap[x][y] == '.' && CanPut(x, y)) {
            
            //放置一个碉堡
            cMap[x][y] = 'O';
            solve(k + 1, current + 1);

            //恢复现场
            cMap[x][y] = '.';
        }
        solve(k + 1, current);//不放置碉堡,右子树
    }
}

int main() {
    while (cin >> n && n) {
        for (int i = 0; i < n; i++) {
            cin >> cMap[i];
        }
        iBest = 0;//初始化最优解为0
        solve(0, 0);//从第一个单元格开始搜索
        cout << iBest << "\t";//输出最优解
        cout << endl;
    }
    return 0;
}

正确代码:

示例1-

#include<iostream>
using namespace std;

const int MAXN = 4;
char cMap[MAXN][MAXN];//地图
int iBest;//最优解
int n;//地图大小

//判断在行row和列col处能否配置碉堡
bool CanPut(int row, int col) {
	int i;

	//判断col列上的合法性
	for (i = row - 1; i >= 0; i--) {
		if (cMap[i][col] == 'O')
			return false;
		if (cMap[i][col] == 'X')
			break;
	}
	for (i = row + 1; i < n; i++) {
		if (cMap[i][col] == 'O')
			return false;
		if (cMap[i][col] == 'X')
			break;
	}

	//判断row行上的合法性
	for (i = col - 1; i >= 0; i--) {
		if (cMap[row][i] == 'O')
			return false;
		if (cMap[row][i] == 'X')
			break;
	}
	for (i = col + 1; i < n; i++) {
		if (cMap[row][i] == 'O')
			return false;
		if (cMap[row][i] == 'X')
			break;
	}
	return true;
}

//放置碉堡的深度优先搜索算法
void solve(int k, int current) {
	int x, y;

	//整个地图判断完毕
	if (k == n * n) {
		if (current > iBest) {
			iBest = current;
			return;
		}
	}
	else {
		//将单元数转换为xy坐标
		x = k / n;//行
		y = k % n;//列

		//左子树
		if (cMap[x][y] == '.' && CanPut(x, y)) {

			//放置一个碉堡
			cMap[x][y] = 'O';
			solve(k + 1, current + 1);

			//恢复现场
			cMap[x][y] = '.';
		}
		solve(k + 1, current);//不放置碉堡,右子树
	}
}

int main() {
	while (cin >> n && n) {
		for (int i = 0; i < n; i++) {
			cin >> cMap[i];
		}
		iBest = 0;//最优解初始化为0
		solve(0, 0);//从第一个单元格开始搜索
		cout << iBest << endl;//输出最优解
	}
	return 0;
}

 

示例2--

 【针对错误修改后的】

/*
*	假设我们有一个方形的城市,其街道都是直的。在方形地图上,
	有n行和n列,每个代表一条街道或一堵墙。每个碉堡有4个射击孔,
	分别正对东西南北方向。在每个射击孔配备一架高射机枪。
	我们假设,子弹是如此强大,它的射程可以任意远,并能摧毁它所击中的碉堡。
	墙也是很坚固的,足以阻止子弹的摧毁。
	问题的目标是,在该城市中布置尽可能多的碉堡,而碉堡之间又不会相互摧毁。
	合理布置碉堡的原则是,没有两个碉堡在同一个水平方向或垂直方向,
	除非它们之间有墙相隔。在本题中,假定城市很小(最多4×4),而且有子弹不能贯穿的墙壁。
*/
#include<iostream>
using namespace std;

char cMap[5][5];	//地图
int iBest;		   //最优解
int n;			  //地图大小

//判断在行row和列col处能否配置碉堡
bool CanPut(int row, int col) {
	int i;

	//判断col列上的合法性
	for (i = row - 1; i >= 0; i--) {
		if (cMap[i][col] == 'O')
			return false;
		if (cMap[i][col] == 'X')
			break;
	}
	//判断row行上的合法性
	for (i = col - 1; i >= 0; i--) {
		if (cMap[row][i] == 'O')
			return false;
		if (cMap[row][i] == 'X')
			break;
	}
	return true;
}

//放置碉堡的深度优先搜索算法
void solve(int k, int current) {
	int x, y;

	//整个地图判断完毕
	if (k == n * n) {
		if (current > iBest) {
			iBest = current;
			return;
		}
	}
	else {
		//将单元数转换为xy坐标
		x = k / n;//行
		y = k % n;//列

		//左子树
		if (cMap[x][y] == '.' && CanPut(x, y)) {

			//放置一个碉堡
			cMap[x][y] = 'O';
			solve(k + 1, current + 1);

			//恢复现场
			cMap[x][y] = '.';
		}
		solve(k + 1, current);//不放置碉堡,右子树
	}
}

int main() {
	while (cin >> n && n) {
		for (int i = 0; i < n; i++) {
			cin >> cMap[i];
		}
		iBest = 0;//初始化最优解为0
		solve(0, 0);//从第一个单元格开始搜索
		cout << iBest;//输出最优解
		cout << endl;
	}
	return 0;
}

代码分析:

【示例2--】这段代码实现了一个基于深度优先搜索(DFS)的算法来解决布置碉堡的问题。在地图上放置碉堡时,需要保证每个碉堡之间不能相互摧毁,即两个碉堡不能在同一行或同一列,除非它们之间被隔开的是墙。

      具体地,算法的主要思路是,采用 DFS 算法的思想,从第一个单元格开始逐个位置进行判断,如果该位置可以放置碉堡,则将其放置,并以此为基础继续向下搜索;如果该位置不能放置碉堡,则不做处理并继续向下搜索。搜索过程中需要记录当前已经放置的碉堡的数量当所有空位都被判断完毕时,将当前数量与历史最佳数量比较,更新最佳数量即可。同时,       

      在放置碉堡后,需要及时恢复现场,即撤回放置的碉堡,使得程序能够正确地搜索到剩余的节点。

总之,该算法通过深度优先搜索实现了对于布置碉堡的问题的求解,从而找到在给定地图内布置尽可能多的碉堡的方案。

while (cin >> n && n) {
    for (int i = 0; i < n; i++) {
        cin >> cMap[i];
    }
    iBest = 0;//初始化最优解为0
    solve(0, 0);//从第一个单元格开始搜索
    cout << iBest;//输出最优解
    cout << endl;
}

这段代码使用了一个一维字符数组 cMap 来存储整个地图,其中 cMap[i] 存储第 i 行地图数据。例如:

        4

        .X..

        ....

        XX..

        ....

cMap[0]就是 .X..  ,不能有空格,就是一行字符

for 循环中,程序逐行读入标准输入流中的字符,并将其存储到相应的 cMap 子数组中,从而完成了逐行读入字符来形成 cMap 一维字符数组这一操作。
 


实现过程解析:

这段代码实现了一个深度优先搜索算法,用于解决在一个n * n大小的方形城市中布置尽可能多的碉堡,而碉堡之间又不会相互摧毁的问题。其主要思路为:

  1. 对于每个单元格,判断能否放置一个碉堡。如果可以放置,则将碉堡放置在该单元格上,并继续向下搜索;如果不能放置,则直接向下搜索。

  2. 搜索完整个城市后,记录最优解即可。

具体实现细节如下:

  1. 使用一个二维字符数组cMap来表示城市地图,并使用一个变量iBest来记录当前最优解。

  2. 使用CanPut函数来判断在行row和列col处能否配置碉堡。具体实现方法为,在该单元格所在的行上搜索,从该单元格往上搜索到第一个墙壁或者碉堡,如果碰到的是碉堡,则返回false,否则继续向上搜索;在该单元格所在的列上同理。

  3. 使用solve函数进行深度优先搜索。solve函数有两个参数,k表示当前搜索到第几个单元格,current表示当前已经放置了多少个碉堡。如果整个城市都搜索完毕,则与当前最优解比较,更新最优解;否则,将单元数转换为坐标x和y,如果当前单元格可以放置碉堡,则将碉堡放置在该单元格上,并继续向下搜索;如果不能放置,则直接向下搜索。每次递归结束后,需要将现场恢复(即将该单元格还原为初始状态)。

  4. 在主函数中,循环读入城市地图,初始化最优解为0,并调用solve函数开始搜索。搜索完毕后,输出最优解即可。


算法函数讲解: 

 CanPut函数


CanPut函数的实现分两步。首先是判断列上的合法性,其次是判断行上的合法性:

  1. 判断列上的合法性

为了判断在(row, col)处能否放置一个碉堡,我们需要判断该列中是否有墙或碉堡。具体的实现为:

从row-1向上遍历该列,如果该单元格上面有碉堡,说明不能再往上放置碉堡,返回false; 如果该单元格上面有墙,说明往上可以放置碉堡,退出循环; 如果该单元格上面没有碉堡和墙,则继续向上遍历。

  1. 判断行上的合法性

为了判断在(row, col)处能否放置一个碉堡,我们需要判断该行中是否有墙或碉堡。具体的实现为:

从col-1向左遍历该行如果该单元格左边有碉堡,说明不能再往左放置碉堡,返回false; 如果该单元格左边有墙,说明往左可以放置碉堡,退出循环; 如果该单元格左边既没有碉堡也没有墙,则继续向左遍历。

最后,如果该单元格同时满足列上和行上的要求,则说明在(row, col)处可以放置一个碉堡,返回true;否则,返回false。

以下是CanPut函数的完整实现(C++代码):

bool CanPut(int row, int col) {
    // 判断列上的合法性
    for (int i = row - 1; i >= 0; i--) {
        if (cMap[i][col] == 'O') {  // 该单元格上面有碉堡,不能放置
            return false;
        }
        if (cMap[i][col] == 'X') {  // 该单元格上面有墙,可以放置
            break;
        }
    }

    // 判断行上的合法性
    for (int j = col - 1; j >= 0; j--) {
        if (cMap[row][j] == 'O') {  // 该单元格左边有碉堡,不能放置
            return false;
        }
        if (cMap[row][j] == 'X') {  // 该单元格左边有墙,可以放置
            break;
        }
    }

    return true;
}

总之,CanPut函数的实现就是为了判断在(row, col)处能否放置一个碉堡。对于每一个空白的单元格,它必须满足列上和行上都没有碉堡才能放置碉堡,否则会与已经放置的碉堡发生冲突,导致方案不可行。


solve函数

solve函数是基于深度优先搜索实现的,用来放置碉堡并求解最优解。该函数的参数k表示搜索的单元格序号,current表示当前已经放置的碉堡数量。

首先判断当前的单元格是否可以放置碉堡,如果可以,则在该位置放置碉堡,继续搜索下一个单元格进行递归操作。如果不能放置碉堡,则直接跳过该单元格,继续搜索下一个单元格进行递归操作。

当搜索到最后一个单元格时,需要判断当前放置的碉堡数量是否是历史最优解,如果是则更新最优解。

在递归过程中,通过回溯操作可以将状态恢复到先前的状态。当搜索完成后,返回最优解的数量。

整个solve函数的实现,就是一个通过深度优先搜索找出符合要求的所有放置策略,然后取其中的最优策略的过程。

总体的递归实现过程可以简述如下:

  1. 判断当前单元格能否放置碉堡
  2. 如果可以,在该位置放置碉堡,继续搜索下一个单元格进行递归操作
  3. 如果不能,直接跳过该单元格,继续搜索下一个单元格进行递归操作
  4. 当搜索到最后一个单元格时,判断当前方案是否是最优解
  5. 通过回溯操作将状态恢复到先前的状态
  6. 返回最优解数量


运行结果:

1--

2--- 

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

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

相关文章

勇创世界一流!移动云为我国数字经济发展提供有力支撑

今年2月&#xff0c;中共中央、国务院印发了《数字中国建设整体布局规划》&#xff0c;通过顶层设计及布局&#xff0c;擘画了我国数字经济发展蓝图。近日在国新办举行的第六届数字中国建设峰会新闻发布会上&#xff0c;相关负责人也对我国数字经济现阶段取得的成绩进行了总结&…

IPWorks VoIP 2022 Crack

网络电话组件 IPWorks VoIP 提供 SIP 和 IVR 组件&#xff0c;旨在促进 CTI 应用程序中的常见 VoIP 操作。快速集成功能以建立拨出电话、接听来电以及根据您的自定义 IVR 菜单路由呼叫。还支持其他 SIP 功能&#xff0c;例如文本到语音、播放预先录制的消息、通话录音和电话会议…

总结:helm

一、介绍 Helm是k8s的包管理工具&#xff0c;类似Linux系统常用的 apt、yum等包管理工具&#xff0c;基于go 语言开发。使用helm可以简化k8s应用部署 二、基本概念 Helm的基本概念 Chart&#xff1a;一个 Helm 包&#xff0c;其中包含了运行一个应用所需要的镜像、依赖和资源…

flask实际开发:flask和nginx如何配置支持websocket

使用pycharm启动flask项目有坑&#xff0c;先修改pycharm设置 1、点击Edit Confiturations 2、配置启动方式 1 新增启动配置 2 选择使用python命令执行 3 给配置设置一个名字 4 设置要启动的模块的位置&#xff0c;flask基本都是app.py 模块 最后别忘记&#xff1a;点击右侧的…

Linux网络-传输层UDP/TCP详解

目录 计算机网络的层状结构 UDP协议 UDP报文格式 理解UDP/TCP报文的本质 UDP的特点 UDP的缓冲区 sendto/recvfrom/send/recv/write/read IO类接口 UDP是全双工的 UDP注意事项 UDP协议&#xff0c;实现简单聊天室&#xff08;服务端客户端&#xff09; TCP协议 TCP协…

SpringBoot集成 ElasticSearch

Spring Boot 集成 ElasticSearch 对于ElasticSearch比较陌生的小伙伴可以先看看ElasticSearch的概述ElasticSearch安装、启动、操作及概念简介 好的开始啦~ 1、基础操作 1.1、导入依赖 <dependency><groupId>org.springframework.boot</groupId><arti…

【是C++,不是C艹】 第一个C++程序 | 命名空间 | 输入输出

&#x1f49e;&#x1f49e; 欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e; &#x1f449;专栏&#xff1a;《是C&#xff0c;不是C艹》&#x1f448; 前言&#xff1a; 在认识了C的来历之后&#xff0c;我们就要开始正式学习C了&#xff0c;系好安全带&#xff0c;准备…

阿里云安全ACP认证考试实验之云盾之云安全中心与态势感知入门体验

“更多玩转云产品” 1、实验概述 通过本实验可对云安全中心&#xff0c;态势感知的一些基本操作有深入了解以及如何来对实例进行安全监控 2、实验目标 完成此实验可以掌握的能力有&#xff1a; 在安骑士中添加白名单、登录安全设置 通过态势感知查看实例的相关告警威胁 3…

数值区间的模糊匹配,二分查找的应用

先看图: 需求很明确,要根据左边的值,显示右边的值。 比如,现在拿到的值是 17.12,那么应该显示成 15;拿到 17.599 ,那么应该显示成 20. 先找规律: 为了便于说明,暂且将左边的值设为 x, 右边的值设为 y. 第一行和最后一行可以写死成 0 与 1500;余下的每行,x 的区间是…

Vue CLI 创建一个项目

vue create 运行以下命令来创建一个新项目&#xff1a; vue create hello-world警告 如果你在 Windows 上通过 minTTY 使用 Git Bash&#xff0c;交互提示符并不工作。你必须通过 winpty vue.cmd create hello-world 启动这个命令。不过&#xff0c;如果你仍想使用 vue crea…

发布会前准备新闻通稿的重要性,为什么媒体不会原稿发布报道?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体 胡老师。 最近有宣传的小伙伴问胡老师&#xff0c;为什么我们精心准备的新闻通稿&#xff0c;媒体没有按照稿子发布呢&#xff1f;今天就与大家交流下这方面的经验。 一&#xff0c;发布会前准备新…

中断嵌套实验

使用汇编语言&#xff0c;要求&#xff1a; 外部中断1可以嵌套外部中断0 没有中断时&#xff0c;8个LED发光二极管以0.1s的速度闪烁。 有外部中断0时&#xff0c;8个LED发光二极管以0.1s的速度流水点亮。&#xff08;中断子程序0&#xff09; 有外部中断1时&#xff0c;会打断外…

还在为招生发愁?一文get中外合办院校招生技巧

生源&#xff0c;是任何一所高校的生存之本和生命线。因此&#xff0c;正确的招生策略&#xff0c;对于院校来说显得格外重要。 近几年&#xff0c;越来越多的家长和学生开始关注中外合办大学&#xff0c;随之而来的中外合办大学的生源竞争也越来越激烈。那么&#xff0c;有哪…

学好虚拟化,首先要学Linux

上次讲到了虚拟化的基础知识&#xff0c;比如虚拟化的应用、各个厂商都是通过何种技术路径来实现的等等&#xff0c;本篇想记录一下我学习到的CPU内存虚拟化和网络虚拟化相关知识&#xff0c;通过记录来制造反馈&#xff0c;让自己更有效地学习。需要注意的是&#xff0c;学习虚…

这 7个 AI 写作助手,太实用了

想象一下&#xff1a;你正在办公桌前为你的广告输入标题&#xff0c;但你突然思维阻塞并卡住了&#xff0c;可惜这时还没有神奇的软件可以帮助你想出点子。或许是有的&#xff1f; 2023 年&#xff0c;AI 写作工具似乎不可避免地会很快融入我们的工作流程中。现代知识工作者已…

政府大数据中心数据资源平台建设方案WORD2022

本资料来源公开网络&#xff0c;仅供个人学习&#xff0c;请勿商用&#xff0c;如有侵权请联系删除 1.1 项目建设内容 对于本次区级大数据资源平台的建设&#xff0c;将按照“总体规划一步到位&#xff0c;平台建设分步实施&#xff0c;数据赋能逐步升级”的原则&#xff0c;落…

理解什么是DTO?什么是AutoMapper?

什么是DTO? .Net DTO是一个对象&#xff0c;它定义了数据如何在网络上发送。它只用于发送和接收数据&#xff0c;不包含任何业务逻辑。使用DTO的原因有以下几个&#xff1a; 将服务层与数据库层分离隐藏客户端不需要查看的特定属性省略一些属性以减少有效负载大小处理嵌套对象…

【LeetCode: 233. 数字 1 的个数 | 暴力递归=>记忆化搜索=>动态规划 | 数位dp】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

Term Suggester 中 suggest_mode 的三种模式missing、popular、always 的区别

1、Term Suggester term suggester 正如其名&#xff0c;只基于 tokenizer 之后的单个 term 去匹配建议词&#xff0c;并不会考虑多个term之间的关系 POST <index>/_search { "suggest": {"<suggest_name>": {"text": "<s…

VM——VMware装Centos

一、创建虚拟机配置 打开VMware&#xff0c;创建新虚拟机 选择自定义&#xff0c;下一步 选择16.x&#xff0c;然后下一步 选择稍后安装&#xff0c;然后下一步 选择Linux、镜像版本&#xff0c;然后下一步 输入虚拟机名称&#xff0c;选择存放位置&#xff0c;然后下一步 选择…