纯小白蓝桥杯备赛笔记--DAY9(搜索)

文章目录

    • 三道例题学会DFS剪枝
      • 什么是剪枝
      • 数字王国之军训排队--2942
      • 特殊的三角形--3008
      • 特殊的多边形--3075
    • DFS基础回溯
      • 简介
      • 回溯法模版
      • 例题
        • N皇后--1508
        • 小朋友崇拜圈--182
        • 全球变暖--178
    • 记忆化搜索
      • 简介
      • 斐波那契数列
      • 混境之地5-3820
      • 地宫取宝-216

三道例题学会DFS剪枝

什么是剪枝

  • 其实就是将搜索过程当中一些不必要的部分直接别除掉,因为搜索过程构成了一棵树,别除不必要的部分,就像是在树上将树枝剪掉,故名剪枝。
  • 剪枝是回溯法的一种重要优化手段,方法往往先写一个暴力搜索,然后找到某些特殊的数学关系,或者逻辑关系,通过它们的约束让搜索树尽可能浅而小,从而达到降低时间复杂度的目的。
  • 一般来说,剪枝的复杂度难以计算。

进入例题提示:如果理解不了的同学建议先看第二部分DFS回溯。

数字王国之军训排队–2942

在这里插入图片描述

  • 向下递归的搜索过程。这里的剪枝策略是当中间出现不合法的情况就跳过。
  • 如果不剪枝就是留到递归出口那去检查,这样做效率是比较慢的。
  • 先写一段不剪枝的方法对比一下。
#include<bits/stdc++.h>
using namespace std;
const int N=15;
int a[N],n;
vector<int>v[N];//存放队伍,例:v1就是队伍1中所有成员的 编号,v2是队伍2中所有成员的编号 
//搜索,dfs返回在cnt个队伍的情况下能否成功分组 
bool dfs(int cnt,int dep)//这里的cnt是队伍的个数 
{
	if(dep==n+1)//递归出口,每个人都成功分组了 
	{return true; 
		//检查当前方案的合法性
		 for(int i=1;i<=cnt;i++)//对每一个队伍进行检查 
		 {
		 	for(int j=0;j<v[i].size();j++)
			 {
			 	for(int k=j+1;k<v[i].size();k++)//这两个循环是枚举所有的二元组 
			 	{
//			 		if(j==k)continue;//相等,退出,注释掉的原因是k从j+1开始,不会相等 
					 if(v[i][k]%v[i][j]==0)return false; 
				 }
			  } 
		  } 
		return true;
	 } 
	 //枚举每一个所属的队伍
	 for(int i=1;i<=cnt;i++)
	 {
	 	v[i].push_back(a[dep]);
	 	if(dfs(cnt,dep+1))return true;//合法
		 //恢复现场
		 v[i].pop_back(); 
	  } 
	  return false;//不存在 
 } 

int main()
{
 	cin>>n;
 	for(int i=1;i<=n;i++)cin>>a[i];
 	sort(a+1,a+n+1);//排序是不影响结果的 
 	//枚举这n个队伍,极端情况就是每个人单独成一队 
	for(int i=1;i<=n;i++)
	{
		if(dfs(i,1));//在i个队伍的情况下,检查深度为1层,如果当前可以成功分组,那么i就是最小的分组个数 
		{
			cout<<i<<'\n';
			break;//找到结果就可以跳出循环了 
		}
	}
	return 0;
 } 
  • 接下来看剪枝的写法:
#include<bits/stdc++.h>
using namespace std;
const int N=15;
int n;
int a[N];
vector<int> vec[N];//二维vector这样定义,别用vector<vector<int>> vec,因为前者外部vector已声明大小,可以直接调用迭代器,后者不行 
bool dfs(int dep,int i)//dep为第几个学生,i为分几队 
{//dfs用于判断是否可以分为i队 
    if(dep==n+1) return true;//如果递归到了最底层,说明可以分成i队 

    for(int j=0;j<i;j++)//将当前dep学生分到j队 
    {    bool flag=false;
        for(const auto &b:vec[j]) //遍历二维vector,遍历vector用auto枚举比较方便, 
        {
        //这种题型与组合枚举不一样,不要用两条件来思考 
            if(a[dep]%b==0) //如果当前将要入队的数字学生与队里面的数字可以整除,即有倍数关系 
            {                 //因为用sort排过序,所以a[dep]一定比b大 
                flag=true;break;
            }
             
            
        }
        if(flag) continue;
        vec[j].push_back(a[dep]);
        if(dfs(dep+1,i)) return true;//布尔dfs的递归这样写,若为false仍需执行后面的恢复现场语句 
        //恢复现场 
        vec[j].pop_back();
    }
    return false; //中间执行完后没有return true,则return false 
}
int main()
{
 	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
     for(int i=1;i<=n;i++)//将1到n队都试试 
     {
         if(dfs(1,i)) //第一个可行的队即为最少的队 
         {
             cout<<i;
             break;
         }
     }
    return 0;
}

特殊的三角形–3008

在这里插入图片描述

  • 解析:
    在这里插入图片描述
  • 具体实现:
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+9;
int n;
int st;
int cnt[N];//乘积为i的三元组有多少个
int prefix[N];//定义前缀和数组 
//dfs
void dfs(int dep,int st,int mwl,int sum)//sum是前面两条边的和 
{
	//剪枝
	if(mwl>1e6) return ;
	if(dep==4)
	{
		cnt[mwl]++;
		return;
	}
	int up=pow(1e6/mwl,1.0/(3-dep+1))+3;//得到上限
	for(int i=st+1;i<(dep==3?sum:up);i++)
	{
		dfs(dep+1,i,mwl*i,sum+i);
	 } 
 } 
int main()
{
 	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
  	dfs(1,0,1,0);
	for(int i=1;i<=1e6;i++)
	{
	    prefix[i]=prefix[i-1]+cnt[i];
	 } 
	 int q;cin>>q;
	 while(q--)
	 {
	 	int l,r;cin>>l>>r;//输入区间
		 cout<<prefix[r]-prefix[l-1]<<"\n"; 
	 }
    
    return 0;
}

特殊的多边形–3075

和上一题比较像,只需要修改部分内容如下:

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+9;
int n;
int st;
int cnt[N];//乘积为i的三元组有多少个
int prefix[N];//定义前缀和数组 
//dfs
void dfs(int dep,int st,int mwl,int sum)//sum是前面两条边的和 
{
	//剪枝1
	if(mwl>1e5) return ;
	if(dep==n+1)
	{
		cnt[mwl]++;
		return;
	}
	//剪枝2 
	int up=pow(1e6/mwl,1.0/(n-dep+1))+3;//得到上限
	//剪枝3,构造递增 
	for(int i=st+1;i<(dep==n?min(sum,up):up);i++)//虽然是n边形,但是最后一位的长度依然不能超过sum 
	{
		dfs(dep+1,i,mwl*i,sum+i);
	 } 
 } 
int main()
{
 	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0); 
	 int q;cin>>q>>n;
	 dfs(1,0,1,0);
	for(int i=1;i<=1e5;i++)
	{
	    prefix[i]=prefix[i-1]+cnt[i];
	 }
	 while(q--)
	 {
	 	int l,r;cin>>l>>r;//输入区间
		 cout<<prefix[r]-prefix[l-1]<<"\n"; 
	 }
    
    return 0;
}

DFS基础回溯

简介

  • 回溯法一般使用DFS(深度优先搜索)实现,DFS是一种遍历或搜索图、树或图像等数据结构的算法,当然这个图、树未必要存储下来(隐式处理就是回溯法),常见的是通过某种关系构造出的搜索树,搜索树一般是排列型搜索树(总节点个数一般为n!级别)和子集型搜索树(总节点个数一般为2^n级别)。
  • 排列型就是每次枚举选哪个,子集型就是对于每一个元素选或不选(结果与顺序无关)。
  • DFS从起始节点开始,沿着一条路径尽可能深入地搜索(一条路走到黑),直到无法继续为止,然后回潮到前一个节点,继续探索其他路径,直到遍历完整个图或树。
  • DFS使用栈或递归来管理节点的遍历顺序,一般使用递归。很多时候DFS和回溯法不必过度区分。
  • 排列树图解:1~3的全排列
    在这里插入图片描述
  • 子集树在这里插入图片描述

回溯法模版

//求1~n的全排列
int a[N];
bool vis[N];//表示是否被使用过
void dfs(int dep)//dep表示深度 
{
	//1.首先考虑递归出口的问题 
	if(dep==n+1)
	{
		for(int i=1;i<=n;i++) cout<<a[i]<<' ';
		cout<<"\n";
		return;
	}
	//2.向下搜索
	for(int i=1;i<=n;i++)
	{
		//2.1先排除不合法的路径
		if(vis[i]) continue;//表示i已经被使用过,全排列中1 2 1这种形式不能出现
		//2.2修改状态
		vis[i]=true;
		a[dep]=1;//i可以被使用,并且此时的递归层达到i
		//2.3下一层
		dfs(dep+1);
		//2.4恢复现场
		vis[i]=false;
		//a[dep]=0可以省略 
	 } 
 } 

例题

N皇后–1508

在这里插入图片描述

  • 分析
    在这里插入图片描述
#include<iostream>
using namespace std;

const int N = 12;
int vis[N][N], n, ans;

void dfs(int dep)
{
    // 在这个搜索中dep表示行,i表示列
    // 1 搜索出口
    if(dep == n + 1)
    {
        ans++;
        return;
    }
    // 2 继续搜索
    for(int i = 1; i <= n; ++i)
    {
        // 2.1 排除非法情况
        if(vis[dep][i])
            continue;
        // 2.2 改变状态
        for(int _i = 1; _i <= n; ++_i)
            vis[_i][i]++;
        for(int _i = dep, _j = i; _i >= 1 && _j >= 1; --_i, --_j)
            vis[_i][_j]++;
        for(int _i = dep, _j = i; _i <= n && _j >= 1; ++_i, --_j)
            vis[_i][_j]++;
        for(int _i = dep, _j = i; _i >= 1 && _j <= n; --_i, ++_j)
            vis[_i][_j]++;
        for(int _i = dep, _j = i; _i <= n && _j <= n; ++_i, ++_j)
            vis[_i][_j]++;
        // 2.3 下一层
        dfs(dep + 1);
        // 2.4 还原现场
        for(int _i = 1; _i <= n; ++_i)
            vis[_i][i]--;
        for(int _i = dep, _j = i; _i >= 1 && _j >= 1; --_i, --_j)
            vis[_i][_j]--;
        for(int _i = dep, _j = i; _i <= n &&  _j >= 1; ++_i, --_j)
            vis[_i][_j]--;
        for(int _i = dep, _j = i; _i >= 1 && _j <= n; --_i, ++_j)
            vis[_i][_j]--;
        for(int _i = dep, _j = i; _i <= n && _j <= n; ++_i, ++_j)
            vis[_i][_j]--;
    }
}

int main()
{
    cin >> n;
    dfs(1);
    cout << ans << "\n";
    return 0;
}

小朋友崇拜圈–182

在这里插入图片描述

  • 解析
    在这里插入图片描述
  • 代码:
#include<bits/stdc++.h>
using namespace std;
const int N= 1e5 + 10;
int a[N],dfn[N]; 
int n,idx,mindfn;
int dfs(int b)
{
    dfn[b]=++idx;//时间戳 
    if(dfn[a[b]]==0) return dfs(a[b]);//要有return ,若时间戳为空,继续递归 
    else//有时间戳的情况 
    {
        if(dfn[a[b]]>=mindfn) return dfn[b]-dfn[a[b]]+1;//下一个崇拜对象大于等于最小时间戳,说明闭环 
        return 0;//下一个崇拜对象小于最小时间戳,说明不闭环 
    }
}
int main()
{ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    int maxs=0;
    for(int i=1;i<=n;i++) //从dfn为空的开始递归 
    {
        if(dfn[i]==0)
        {
            mindfn=idx+1;//更新最小时间戳 
        maxs=max(dfs(i),maxs);//取所有环中的最大值 
        }
    }
    cout<<maxs<<endl;    
    return 0;
}

  • 第二种形式–dfs中有一点点不同
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e5+9;
int n,a[N],dfn[N],mindfn;
int idx;//这是一个正在变化的数字,表示此时的时间 
int ans;
int dfs(int x)
{
	dfn[x]=++idx;
	//递归出口 
	if(dfn[a[x]])
	{
		if(dfn[a[x]]>=mindfn)
		return dfn[x]-dfn[a[x]]+1;
	 	return 0;	
	}
	return dfs(a[x]); 
}
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i];
	for(int i=1;i<=n;i++)
	{
		if(!dfn[i])
		{
			mindfn=idx+1;//更新
			ans=max(ans,dfs(i)); 
		}
	}
	cout<<ans<<endl;
}
全球变暖–178

在这里插入图片描述

  • 分析:在这里插入图片描述
  • 代码:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e3+5;
int n;
char mp[N][N];
int scc,col[N][N];
int dx[]={0,0,1,-1};//表示四个方向的偏移量
int dy[]={1,-1,0,0}; 
bool vis[N*N];//表示某种颜色是否剩下来 
void dfs(int x,int y)
{
	col[x][y]=scc; 
	for(int i=0;i<4;i++)//i往四个方向走 
	{
		int nx=x+dx[i];//下一个x的位置
		int ny=y+dy[i];
		if(col[nx][ny]||mp[nx][ny]=='.')continue;//海洋!不要过去 
//		第一个条件是说:如果已经有颜色了就不要再走,否则会造成两个点反复横跳 
		dfs(nx,ny);//因为题干中保证了边缘是海洋,所以不用判断了 
	}
 } 
int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)cin>>mp[i]+1;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(col[i][j]||mp[i][j]=='.')continue;//如果是海洋,跳过
			scc++;//当前的颜色编号加1 
			dfs(i,j);
		}
	}
	//进行淹没
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(mp[i][j]=='.')continue;//特判,防止超出地图 
			bool tag=true;//默认颜色会剩下来(四个方向都有陆地)
			for(int k=0;k<4;k++)//往四个方向走 
			{
				int x=i+dx[k];
				int y=j+dy[k];
				if(mp[x][y]=='.')tag=false;
			 } 
			 if(tag)
			 {
			 	if(!vis[col[i][j]])ans++;//如果这个颜色没有出现过,答案++ 
			 	vis[col[i][j]]=true; 
			 }
		 } 
	 } 
	 cout<<scc-ans<<endl;
	 return 0;
}

记忆化搜索

简介

  • 就是将搜索过程中会重复计算且结果相同的部分保存下来,作为一个状态,下次访问到这个状态时直接将这个子搜索的结果返回,而不需要再重新算一遍。
  • 通常会使用数组map来进行记忆化,下标一般和dfs的参数表对应。
  • 注意使用记忆化需要保证重复计算的结果是相同的,否则可能产生数据失真。

斐波那契数列

在这里插入图片描述
如果直接采用递归来做,时间复杂度将接近O(2^),但是我们会发现有大部分的重复计算,比如F[n- 2]在求F[n]的时候算过,在求F[n-1]的时候又被算了一次,而F[1]计算次数更多了,但它们在重复的时候的结果是相同的,所以可以采用记忆化(也叫带备忘录的搜索)。

  • 如果采用原来的方法:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll p=1e9+7;
const int inf=1e9,N=1e3+3;
ll f(int n)
{
	if(n<=2)return 1;
	else
	return (f(n-1)+f(n-2))%p;
}

int main()
{
	int n;cin>>n;
	cout<<f(n)<<endl;
	return 0;
}

可以发现,当输入值为50的时候计算就非常慢了。

  • 增加备忘录:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll p=1e9+7;
const int inf=1e9,N=1e5+3;
ll dp[N];
ll f(int n)
{
	if(n<=2)return 1;
	if(dp[n]!=-1)return dp[n];//被算过才能直接返回 
	else
	return dp[n]=(f(n-1)+f(n-2))%p;
}

int main()
{
	memset(dp,-1,sizeof dp);//初始化dp数组 ,dp为-1代表还没有被算过 
	int n;cin>>n;
	cout<<f(n)<<endl;
	return 0;
}

这下输入5000也可以直接算出来啦。
在这里插入图片描述

  • 之前的文章中提到过memset函数,这里再次说一下用法:

C++中的memset函数用于将一段内存区域的内容设置为指定的值。它的原型如下:
cpp
复制代码运行
void* memset(void* ptr, int value, size_t num);
参数说明:
ptr:指向要填充的内存区域的指针。
value:要设置的值,以int形式给出,但实际上是按unsigned char类型处理的。
num:要设置的字节数。
返回值:返回指向填充后的内存区域的指针。

混境之地5-3820

在这里插入图片描述

  • 未加记忆化搜索:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e3+3;
int n,m,k;//起点,终点和高度
int sx,sy,fx,fy; 
int h[N][N];//高度数组 
int dx[]={0,0,1,-1};//表示四个方向的偏移量
int dy[]={1,-1,0,0}; 
bool inmap(int x,int y)//判断是否在地图之中 
{
	return 1<=x&&x<=n&&1<=y&&y<=m; 
}
//返回值表示能否到达终点(fx,fy)
bool dfs(int x,int y,int t)//t表示当前使用的喷气背包的次数 
{
	if(x==fx&&y==fy)return true;//到达终点
	 for(int i=0;i<4;i++)
	 {
	 	int nx=x+dx[i];//下一个方向
	    int ny=y+dy[i];
		if(!inmap(nx,ny))continue;//不在地图内,返回
		if(!t)//没用过背包 
		{
			//不用 
			if(h[x][y]>h[nx][ny]&&dfs(nx,ny,0))return true; 
			//用
			if(h[x][y]+k>h[nx][ny]&&dfs(nx,ny,1))return true; 
		 }
		 else
		 {
		  	//只能不用 
			if(h[x][y]>h[nx][ny]&&dfs(nx,ny,1))return true;
		  } 
	 }
	 return false; 
 } 
int main()
{
	//控制输入 
	cin>>n>>m>>k;
	cin>>sx>>sy>>fx>>fy;
 	for(int i=1;i<=n;i++)
 	{
 		for(int j=1;j<=m;j++)
 		{
 			cin>>h[i][j];
		 }
	 }
	 cout<<(dfs(sx,sy,0)?"Yes":"No")<<endl;
	return 0;
}
  • 加上记忆化搜索:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=1e3+3;
int n,m,k;//起点,终点和高度
int sx,sy,fx,fy; 
int h[N][N];//高度数组 
int dx[]={0,0,1,-1};//表示四个方向的偏移量
int dy[]={1,-1,0,0}; 
int dp[N][N][2];//这里不能用bool 
bool inmap(int x,int y)//判断是否在地图之中 
{
	return 1<=x&&x<=n&&1<=y&&y<=m; 
}
//返回值表示能否到达终点(fx,fy)
bool dfs(int x,int y,int t)//t表示当前使用的喷气背包的次数 
{
	if(x==fx&&y==fy)return true;//到达终点
	if(dp[x][y][t]!=-1)return dp[x][y][t];
	 for(int i=0;i<4;i++)
	 {
	 	int nx=x+dx[i];//下一个方向
	    int ny=y+dy[i];
		if(!inmap(nx,ny))continue;//不在地图内,返回
		if(!t)//没用过背包 
		{
			//不用 
			if(h[x][y]>h[nx][ny]&&dfs(nx,ny,0))return dp[x][y][t]=true; 
			//用
			if(h[x][y]+k>h[nx][ny]&&dfs(nx,ny,1))return dp[x][y][t]=true; 
		 }
		 else
		 {
		  	//只能不用 
			if(h[x][y]>h[nx][ny]&&dfs(nx,ny,1))return dp[x][y][t]=true;
		  } 
	 }
	 return dp[x][y][t]=false; 
 } 
int main()
{
	memset(dp,-1,sizeof dp);
	//控制输入 
	cin>>n>>m>>k;
	cin>>sx>>sy>>fx>>fy;
 	for(int i=1;i<=n;i++)
 	{
 		for(int j=1;j<=m;j++)
 		{
 			cin>>h[i][j];
		 }
	 }
	 cout<<(dfs(sx,sy,0)?"Yes":"No")<<endl;
	return 0;
}

地宫取宝-216

在这里插入图片描述

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const ll p=1e9+7;
const int N=55;
int n,m,k;//起点,终点和高度
int c[N][N];//高度数组 
int dx[]={0,1};//表示四个方向的偏移量
int dy[]={1,0}; 
int dp[N][N][15][15];//这里不能用bool 
bool inmap(int x,int y)//判断是否在地图之中 
{
    return 1<=x&&x<=n&&1<=y&&y<=m; 
}
//表示从(1,1)到(x,y),有cnt件宝贝,且最大值为mx的方案数 
ll dfs(int x,int y,int mx,int cnt)//t表示当前使用的喷气背包的次数 
{
    if(x==n&&y==m)return (ll)(cnt==k);//到达终点
    if(dp[x][y][mx][cnt]!=-1)return dp[x][y][mx][cnt];
    ll res=0;//方案数 
    for(int i=0;i<2;i++)
    {
        int nx=x+dx[i];//下一个方向
        int ny=y+dy[i];
        if(!inmap(nx,ny))continue;//不在地图内,返回
        //拿这个宝贝
        if(c[nx][ny]>mx&&cnt<k) res=(res+dfs(nx,ny,c[nx][ny],cnt+1))%p;
        //不拿这个宝贝
        res=(res+dfs(nx,ny,mx,cnt))%p; 
    }
    return dp[x][y][mx][cnt]=res; 
} 
int main()
{
    memset(dp,-1,sizeof dp);
    //控制输入 
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>c[i][j];
            c[i][j]++;
        }
    }
    cout<<(dfs(1,1,0,0)+dfs(1,1,c[1][1],1))%p;//不拿和拿了 
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

云计算迎变局:阿里云、腾讯云“各有千秋”

毋庸置疑&#xff0c;无论在什么时候什么行业&#xff0c;低价策略都是一柄利器。比如&#xff0c;在电商行业&#xff0c;除了拼多多将低价策略贯彻到底之外&#xff0c;淘宝、京东也将性价比作为发力重点&#xff0c;并通过补贴、秒杀等方式&#xff0c;再度强调自身的“价格…

Pygame基础8-碰撞

Collisions 在Pygame中&#xff0c;我们使用矩形来移动物体&#xff0c;并且用矩形检测碰撞。 colliderect检测两个矩形是否碰撞&#xff0c;但是没法确定碰撞的方向。 Rect1.colliderect(Rect2) # collision -> return Ture # else -> return Falsecollidepoint可以…

数据结构——遍历二叉树和线索二叉树,树和森林

目录 1.遍历的算法实现 1.先序遍历 代码示例&#xff1a; 2.中序遍历 代码示例&#xff1a; 3.后序遍历 代码示例&#xff1a; 4.遍历算法的分析 2.遍历二叉树的非递归算法 1.中序遍历非递归算法 代码示例&#xff1a; 3.二叉树的层次遍历 代码示例&#xff1a; 4.二…

C#/.NET/.NET Core优秀项目和框架2024年3月简报

前言 公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架&#xff08;每周至少会推荐两个优秀的项目和框架当然节假日除外&#xff09;&#xff0c;公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等&#xff08;打不开或者打开GitHub很慢的同学…

BUUCTF [安洵杯 2019]吹着贝斯扫二维码 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 密文&#xff1a; 下载附件解压&#xff0c;得到很多没有后缀的文件和一个ZIP压缩包。 解题思路&#xff1a; 1、首先&#xff0c;查看ZIP压缩包&#xff0c;发现有密码&#xf…

GreatSQL 优化技巧:将 MINUS 改写为标量子查询

GreatSQL 优化技巧&#xff1a;将 MINUS 改写为标量子查询 前言 minus 指令运用在两个 SQL 语句上&#xff0c;取两个语句查询结果集的差集。它先找出第一个 SQL 所产生的结果&#xff0c;然后看这些结果有没有在第二个 SQL 的结果中&#xff0c;如果在&#xff0c;那这些数据…

2024年山东临沂教育人才引进报名流程

2024年山东临沂教育人才引进报名流程

表单全选反选(前端)

1.Html和JavaScript <table><tr><th class"allCheck"><input type"checkbox" name"" id"checkAll"> <span class"all">全选</span></th><th>商品</th><th>商…

Hive函数笔试题(简单)

第1题 有如下的用户访问数据 userId visitDate visitCount u01 2017/1/21 5 u02 2017/1/23 6 u03 2017/1/22 8 u04 2017/1/20 3 u01 2017/1/23 6 u01 2017/2/21 8 u02 2017/1/23 6 u01 2017/2/22 4 要求使用SQL统计出每个用户的累积访问次数&…

Qt中继承QCheckBox的类结合QTableWidget实现多选并且每个多选的id都不一样

1.相关描述 继承QCheckBox的类MyCheckBox&#xff0c;利用QTableWidget的setCellWidget方式添加MyCheckBox类的对象 2.相关页面 3.相关代码 mycheckbox.h #ifndef MYCHECKBOX_H #define MYCHECKBOX_H#include <QCheckBox> #include <QObject>class MyCheckBox : pu…

DSSS-UQPSK学习笔记

文章目录 非平衡四相键控-直接序列扩频&#xff08;UQPSK-DSSS&#xff09;信号因其能同时传输两路不同功率、不同速率信号的特点&#xff0c;在需要图象和数据综合业务传输的领域得到了广泛应用。 系统信号的调制方式为非平衡四相键控&#xff08;Unbalanced Quadrature Phase…

SpringBoot 整合Redis第1篇

SpringBoot是一个开发框架&#xff0c;Redis是一个高性能的键值存储数据库&#xff0c; 常用于缓存、会话管理、消息队列等应用场景。 定义 Redis是什么&#xff1f; 它是一个存储层级&#xff0c; 在实际项目中&#xff0c;位于关系数据库之上&#xff0c; 类似Android分为5…

vue3封装Element导航菜单

1. 导航外层布局 AsideView.vue <template><el-menu:default-active"defaultActive"class"my-menu":collapse"isCollapse":collapse-transition"false"open"handleOpen"close"handleClose"><menu…

【机器学习入门】拥抱人工智能,从机器学习开始

拥抱人工智能&#xff0c;从机器学习开始 目录&#xff1a; 1. 机器学习&#xff1a;一种实现人工智能的方法2. 机器学习算法&#xff1a;是使计算机具有智能的关键3. Anaconda&#xff1a;初学Python、入门机器学习的首选4. 总结 转载链接&#xff1a;文章-阿里云开发者社区…

PyTorch深度学习入门-1

PyTorch深度学习快速入门教程&#xff08;绝对通俗易懂&#xff01;&#xff09;【小土堆】_哔哩哔哩_bilibili \ PyTorch 和 TensorFlow 是两个深度学习框架&#xff0c;TensorBoard 是 TensorFlow 提供的可视化工具&#xff0c;Transforms是 PyTorch 中用于数据预处理的工具…

可视化图表:K线图,快速搞清价格波动。

2023-08-21 21:20贝格前端工场 Hi&#xff0c;我是贝格前端工场的老司机&#xff0c;本文分享可视化图表设计的K线图设计&#xff0c;欢迎老铁持续关注我们。 一、K线图的含义 K线图&#xff08;K Line Chart&#xff09;是一种常用于股票、期货等金融市场的可视化图表&…

如何将图片识别转文字?这3种工具简单易操作

如何将图片识别转文字&#xff1f;在数字化时代&#xff0c;图片识别转文字技术的需求愈发凸显。无论是处理海量的扫描文档&#xff0c;从中迅速提取关键信息&#xff0c;还是通过照片轻松记录菜单上的文字&#xff0c;这一技术都展现出了其强大的实用性。它极大地提高了我们的…

计算机网络—VLAN 间路由配置

目录 1.拓扑图 2.实验环境准备 3.为 R3 配置 IP 地址 4.创建 VLAN 5.配置 R2 上的子接口实现 VLAN 间路由 6.配置文件 1.拓扑图 2.实验环境准备 配置R1、R3和S1的设备名称&#xff0c;并按照拓扑图配置R1的G0/0/1接口的IP地址。 [Huawei]sysname R1 [R1]interface Giga…

机器视觉/将HIK海康面阵相机连接Halcon软件

文章目录 概述工业相机客户端动态库拷贝Halcon连接HIK相机的配置相机参数其他 概述 本文简述了如何将海康面阵相机连接到Halcon软件中进行实时取图的过程。 补充&#xff0c; 整个实践过程使用 17.12 / x64-win64 Halcon 软件版本 海康 MV-CE200-10GM 面阵相机。从左到右简解…

机器学习周报第35期

目录 一、文献阅读&#xff1a;You Only Look Once: Unified, Real-Time Object Detection1.1 摘要1.2 背景1.3 论文模型1.4 网络设计1.5 YOLO的局限性1.6 实现代码 target 7*7*30 值域为0-1 一、文献阅读&#xff1a;You Only Look Once: Unified, Real-Time Object Detection…