搜索题目综合

2023-11-02

BFS

1、小X学游泳
【题解】枚举每一个点作为连通块的起点,求得连通块大小,然后打擂台求最值即可。
【参考代码】

#include <iostream>
#include <iomanip>
#include <queue>
#include <algorithm>
using namespace std;
char ch[105][105];
int n,m,MAXX; 
int d[4][2]={-1,0,0,1,1,0,0,-1};//上、右、下、左4个方向位移量 
struct node // 存放每个位置的行列坐标  
{
	int x;
	int y;
};

int bfs(int x,int y)
{
	queue<node> Q;
	int sum=1; // 初始为1(包含起始位置) 
	const char c=ch[x][y];//保存水深数据 
	ch[x][y]='0'; // 改变状态 
	Q.push((node){x,y}); // 将起始位置信息入队 
	while(!Q.empty()) // 队非空 
	{
		for(int i=0;i<4;i++) // 搜索上右下左 
		{
			int dx=Q.front().x+d[i][0];//当前行 
			int dy=Q.front().y+d[i][1];//当前列 
			if(dx>=0 && dx<n && dy>=0 && dy<m && ch[dx][dy]==c) // 未越界,水深相同 
			{
				sum++;// 面积加1 
				ch[dx][dy]='0';//标记状态 
				Q.push((node){dx,dy});// 入队 
			}
		}
		Q.pop();//队头出队 
	}
	return sum;
}

int main()
{
	cin>>n>>m;
	for(int i=0;i<n;i++)
	{
		cin>>ch[i];
	}
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(ch[i][j]!='0')
			{
				MAXX=max(MAXX,bfs(i,j)); //调用bfs,打擂台求出每片区域的最大值 
			}	
		}
	}
	cout<<MAXX<<endl;// 完美输出 OK 
	return 0;
} 


2、迷宫出口
【题解】我们曾经用深搜(DFS)的方式写过该题目;我们暴力枚举要走的每一步,以点的坐标作为枚举对象进行枚举即可。
【参考代码】

#include <iostream>
#include <iomanip>
#include <queue>
#include <algorithm>
using namespace std;
int a[105][105];
int n,sx,sy,ex,ey;
int d[4][2]={-1,0,0,1,1,0,0,-1};//上、右、下、左4个方向位移量 
struct node // 存放每个位置的行列坐标  
{
	int x;
	int y;
};

void bfs(int x,int y)
{
	queue<node> Q;
	a[x][y]=1; // 改变状态 
	Q.push((node){x,y}); // 将起始位置信息入队 
	while(!Q.empty()) // 队非空 
	{
		for(int i=0;i<4;i++) // 搜索上右下左 
		{
			int dx=Q.front().x+d[i][0];//当前行 
			int dy=Q.front().y+d[i][1];//当前列 
			if(dx>=1 && dx<=n && dy>=1 && dy<=n && a[dx][dy]==0)// 未越界,能走 
			{
				a[dx][dy]=1;//标记状态 
				Q.push((node){dx,dy});// 入队
				if(dx==ex && dy==ey) // 哇,哇,到了耶!
				{
					cout<<"YES"<<endl; // 输出 
					return ; //结束 
				} 
			}
		}
		Q.pop();//队头出队 
	}
	cout<<"NO"<<endl; // 好难受,无法到达啊 
}

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			cin>>a[i][j];
		}
	}
	cin>>sx>>sy>>ex>>ey;
	if(a[sx][sy]==1) //若起点就无法通行 
	{
		cout<<"NO"<<endl; // 输出NO 
		return 0; // 直接结束吧 ,别搜了
	}
	bfs(sx,sy);
	return 0;
} 

3、走出迷宫的最少步数
【题解】此类问题使用DFS、BFS都可以达到目标。但要注意二者的区别,首先就时间复杂度而言DFS更耗费时间;就搜索顺序而言,虽然二者的搜索解答树是一样的,但是DFS是按照顺序枚举的,可以很容易得到字典序最小的答案序列;而BFS则不是。
【参考代码】

#include <iostream>
#include <iomanip>
#include <queue>
#include <algorithm>
using namespace std;
char ch[50][50];
int n,m;
int d[4][2]={-1,0,0,1,1,0,0,-1};//上、右、下、左4个方向位移量 
struct node // 存放每个位置的行列坐标  步数 
{
	int x;
	int y;
	int step;//步数 
};

void bfs(int x,int y)
{
	queue<node> Q;
	ch[x][y]='#'; // 改变状态 
	Q.push((node){x,y,1}); // 将起始位置信息入队 
	while(!Q.empty()) // 队非空 
	{
		for(int i=0;i<4;i++) // 搜索上右下左 
		{
			int dx=Q.front().x+d[i][0];//当前行 
			int dy=Q.front().y+d[i][1];//当前列 
			if(dx>=1 && dx<=n && dy>=1 && dy<=m && ch[dx][dy]!='#')// 未越界,不是障碍物 
			{
				ch[dx][dy]='#';//标记状态 
				Q.push((node){dx,dy,Q.front().step+1});// 入队
				if(dx==n && dy==m) // 到达右下角 
				{
					cout<<Q.front().step+1<<endl; // 输出步数 
					return ; //结束 
				} 
			}
		}
		Q.pop();//队头出队 
	}
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>ch[i][j];
		}
	}
	bfs(1,1);//从左上角开始 
	return 0;
} 

4、走出迷宫的最少步数2
【题解】与上一题异曲同工,建议自己独立写完整代码
【参考代码】

#include <iostream>
#include <iomanip>
#include <queue>
#include <algorithm>
using namespace std;
char ch[105][105];
int n,m,sx,sy,ex,ey;
int d[4][2]={-1,0,0,1,1,0,0,-1};//上、右、下、左4个方向位移量 
struct node // 存放每个位置的行列坐标  步数 
{
	int x;
	int y;
	int step;//步数 
};

void bfs(int x,int y)
{
	queue<node> Q;
	ch[x][y]='#'; // 改变状态 
	Q.push((node){x,y,0}); // 将起始位置信息入队 
	while(!Q.empty()) // 队非空 
	{
		for(int i=0;i<4;i++) // 搜索上右下左 
		{
			int dx=Q.front().x+d[i][0];//当前行 
			int dy=Q.front().y+d[i][1];//当前列 
			if(dx>=1 && dx<=n && dy>=1 && dy<=m && ch[dx][dy]!='#')// 未越界,不是障碍物 
			{
				ch[dx][dy]='#';//标记状态 
				Q.push((node){dx,dy,Q.front().step+1});// 入队
				if(dx==ex && dy==ey) // 到达终点 
				{
					cout<<Q.front().step+1<<endl; // 输出步数 
					return ; //结束 
				} 
			}
		}
		Q.pop();//队头出队 
	}
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>ch[i][j];
			if(ch[i][j]=='S') // 记录起点位置 
			{
				sx=i;
				sy=j;
			} 
			if(ch[i][j]=='T')//记录终点位置 
			{
				ex=i;
				ey=j;
			}
		}
	}
	bfs(sx,sy);//从起点开始bfs 
	return 0;
} 

5、数池塘
【视频讲解】

数池塘

6、骑士巡游
【题解】该题目与马的遍历非常接近,注意八个方向的方向数组的构造
【参考代码】

#include <bits/stdc++.h>
using namespace std;
int a[15][15];
int d[8][2]={-1,-2,-2,-1,-2,1,-1,2,1,2,2,1,2,-1,1,-2};
struct node
{
	int x;
	int y;
	int step;
};
int n,m,sx,sy,ex,ey;

void bfs(int x,int y)
{
	queue<node> Q;
	Q.push((node){x,y,0});
	while(!Q.empty())
	{
		for(int i=0;i<8;i++) // 马的8个方向 
		{
			int dx=Q.front().x+d[i][0];//新的行 
			int dy=Q.front().y+d[i][1];//新的列 
			int s=Q.front().step+1;//当前步数 
			if(dx>=1 && dx<=n && dy>=1 && dy<=m && a[dx][dy]==0)// 未越界,能走 
			{
				a[dx][dy]=1;// 改变当前点的状态 
				Q.push((node){dx,dy,s});//入队 
				if(dx==ex && dy==ey) //判断,到达目标点 
				{
					cout<<s<<endl;// 输出步数 
					return ;
				}
			}
		}
		Q.pop();
	}
	
}

int main()
{
	cin>>n>>m>>sx>>sy>>ex>>ey;
	a[sx][sy]=1;// 改变起点状态,以便后面不被搜到 
	bfs(sx,sy);// 从起点位置展开bfs 

	return 0;
} 

7、骑士牛
【视频讲解】

骑士牛

8、走出迷宫的最短路径
【题解】此题与迷宫问题一样的,但是最后需要输出路径,所以重点关注路径输出是如何解决的。
【参考代码】

#include <bits/stdc++.h>
using namespace std;
int a[160][160];
int p[160][160][2];// 用于保存来自上一步的行、列号 
int d[4][2]={-1,0,0,1,1,0,0,-1};
struct node
{
	int x;
	int y;
};
int n,m,sx,sy,ex,ey;

void print(int x,int y)
{
	if(x==0 && y==0) return ;//递归边界 
	print(p[x][y][0],p[x][y][1]);//递归上一个:我来自哪里??? 
	cout<<"("<<x<<","<<y<<")"<<"->"; // 利用栈的特性依次输出 
}

void bfs(int x,int y)
{
	queue<node> Q;
	Q.push((node){x,y});//将出发地信息入队 
	while(!Q.empty())
	{
		for(int i=0;i<4;i++) // 4个方向bfs 
		{
			int dx=Q.front().x+d[i][0];//新的行 
			int dy=Q.front().y+d[i][1];//新的列 
			if(dx>=1 && dx<=n && dy>=1 && dy<=m && a[dx][dy]!=1)// 未越界,能通行 
			{
				p[dx][dy][0]=Q.front().x;//记录保存来自的行 
				p[dx][dy][1]=Q.front().y; //记录保存来自的列 
				a[dx][dy]=1;// 改变当前点的状态 
				Q.push((node){dx,dy});//将到达的当前位置信息入队 
				if(dx==ex && dy==ey)//判断,到达目标点 
				{
					print(p[dx][dy][0],p[dx][dy][1]); // 调用递归输出函数 
					cout<<"("<<dx<<","<<dy<<")"<<endl;//最后再输出终点坐标 
					return ;
				}
			}
		}
		Q.pop();
	}
	cout<<"no way"<<endl; // 哇,累死我了,怎么也走不到终点,输出no way 
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
		}
	}
	cin>>sx>>sy;
	cin>>ex>>ey;
	
	p[sx][sy][0]=p[sx][sy][1]=0;//将起始位置的初始值记为0 
	a[sx][sy]=1;//标记,将出发地标记为不能通行 
	bfs(sx,sy);//从起始位置展开bfs 
	
	return 0;
} 

9、泉水
【视频讲解】

泉水

10、最小拐弯路径
【题解】广搜,使用while循环从队列的头部对应的点一直向一个方向走,如果该点能走,判断该点不在队列中,则入队;第一次走到终点时,对应的弯道次数,就是最小弯道次数;
【视频讲解】

最小拐弯路径

DFS

1、卒的遍历
【题解】该题是DFS的模板题,但要注意二点的处理。一是先下后右,可以通过方向数组定义来解决;二是路径输出的处理,此处采用的递归方式输出;
【参考代码】

#include <bits/stdc++.h>
#define P pair<int,int>
using namespace std;
int a[10][10],p[10][10][2];
bool vis[10][10];
int n,m,sum;
int d[2][2]={1,0,0,1};
void print(int x,int y)
{
	if(x==0 && y==0) return ;
	print(p[x][y][0],p[x][y][1]);
	cout<<x<<","<<y<<"->";
}
void dfs(int x,int y)
{
	if(x==n && y==m) // 边界 到达终点 
	{
		sum++;//方案计数 
		cout<<sum<<":"; //当前方案 
		print(p[n][m][0],p[n][m][1]); //递归输出方案 
		cout<<n<<","<<m<<endl;
		return ;
	}
	for(int i=0;i<2;i++) //下 右 2个方向 
	{
		int dx=x+d[i][0];//当前行 
		int dy=y+d[i][1];//当前列 
		if(dx>=1 && dx<=n && dy>=1 && dy<=m && !vis[dx][dy]) //合法,且未访问过 
		{
			p[dx][dy][0]=x;//保存来自行 
			p[dx][dy][1]=y;//保存来自列 
			vis[dx][dy]=true;//标记为已访问 
			dfs(dx,dy); //从当前位置继续一路搜下去 
			vis[dx][dy]=false;//回溯 
		}
	}
}

int main() {
	cin>>n>>m;
	p[1][1][0]=p[1][1][1]=0;//初始为0(递归边界) 
	dfs(1,1);
    return 0;
}

2、马的遍历
【题解】关注输出方式的不同。
【参考代码1】

#include <bits/stdc++.h>
using namespace std;
bool vis[10][10];
int a[10][10][2];
int d[4][2]={2,1,1,2,-1,2,-2,1}; //4个方向位移量 
int sum;
void print(int x,int y)
{
	if(x==0 && y==0)
	{
		cout<<0<<","<<0<<"->";
		return ;
	 } 
	print(a[x][y][0],a[x][y][1]);
	cout<<x<<","<<y<<"->";
}
void dfs(int x,int y)
{
	if(x==4 && y==8) //边界(到达终点) 
	{
		sum++;//方案计数 
		cout<<sum<<":";//输出当前方案数 
		print(a[x][y][0],a[x][y][1]); //递归输出 
		cout<<x<<","<<y<<endl; //最后再输出终点坐标 
		return ;
	}
	for(int i=0;i<4;i++)
	{
		int dx=x+d[i][0];//当前行 
		int dy=y+d[i][1];//当前列 
		if(dx>=0 && dx<=4 && dy>=0 && dy<=8 && !vis[dx][dy])//合法 没来过 
		{
			vis[dx][dy]=true;//标记 
			a[dx][dy][0]=x;//记录来自的行 
			a[dx][dy][1]=y;//记录来自的列 
			dfs(dx,dy);//继续走 
			vis[dx][dy]=false;//回溯 
		}
	}
}
int main() {
	vis[0][0]=true;//标记起点 
	dfs(0,0);
    return 0;
}

【参考代码2】

#include <bits/stdc++.h>
using namespace std;
bool vis[10][10];
int a[200][2];
int d[4][2]={2,1,1,2,-1,2,-2,1}; //4个方向位移量 
int sum;
void dfs(int x,int y,int n)
{
	a[n][0]=x;//记录第n步到达的行数 
	a[n][1]=y;//记录第n步到达的列数 
	if(x==4 && y==8) //边界(到达终点) 
	{
		sum++;//方案计数 
		cout<<sum<<":";//输出当前方案数 
		for(int i=1;i<=n;i++) //输出路径 
		{
			if(i!=1) cout<<"->";
			cout<<a[i][0]<<","<<a[i][1];
		}
		cout<<endl; 
		return ;
	}
	for(int i=0;i<4;i++)
	{
		int dx=x+d[i][0];//当前行 
		int dy=y+d[i][1];//当前列 
		if(dx>=0 && dx<=4 && dy>=0 && dy<=8 && !vis[dx][dy])//合法 没来过 
		{
			vis[dx][dy]=true;//标记 
			dfs(dx,dy,n+1);//继续走 
			vis[dx][dy]=false;//回溯 
		}
	}
}
int main() {
	vis[0][0]=true;//标记起点 
	dfs(0,0,1);
    return 0;
}

3、方格取数

方格取数

4、特殊的质数肋骨
【题解】分离一个数的各个位,暴力枚举去掉最后一位后是否还是质数

特殊的质数肋骨

【参考代码】

#include <bits/stdc++.h>
using namespace std;
int n;

bool is_prime(int x) //质数函数 
{
	if(x<=1) return false;
	int a=sqrt(x);
	for(int i=2;i<=a;i++)
	{
		if(x%i==0) return false;
	}
	return true;
}

void dfs(int x,int m)
{
	if(m==n) //满足要求的位数就输出 
	{
		cout<<x<<endl;
		return ;
	}
	for(int i=1;i<=9;i++)
	{
		if(is_prime(x*10+i)) dfs(x*10+i,m+1); //生成的1位、2位、3位、4位数是质数,递归下去 
	}
}

int main() {
	cin>>n;
	dfs(0,0);//初始  位数 
    return 0;
}

【优化代码】
仔细观察,发现无论生成几位数,首位(一位数)必须为质数,一定是2,3,5,7之一,其他位数是1,3,7,9中的一个,因此复杂度可以大大的优化:

#include <bits/stdc++.h>
using namespace std;
int n;
int a[5]={2,3,5,7},b[5]={1,3,7,9};//首位  其他位 
bool is_prime(int x) //质数函数 
{
	if(x<=1) return false;
	int a=sqrt(x);
	for(int i=2;i<=a;i++)
	{
		if(x%i==0) return false;
	}
	return true;
}

void dfs(int x,int m)
{
	if(m==n) //满足要求的位数就输出 
	{
		cout<<x<<endl;
		return ;
	}
	for(int i=0;i<4;i++)
	{
		if(is_prime(x*10+b[i])) dfs(x*10+b[i],m+1); //生成的1位、2位、3位、4位数是质数,递归下去 
	}
}

int main() {
	cin>>n;
	for(int i=0;i<4;i++) //从首位开始递归下去 
	{
		dfs(a[i],1);
	} 
    return 0;
}

5、古希腊之争(二)

#include<iostream>
using namespace std;
char ch[25][25];
bool vis[25][25];
int d[4][2]={-1,0,0,1,1,0,0,-1};
int n,m,starx,stary,endx,endy,minn=0x3f;
 
void dfs(int x,int y,int t)
{
	if(x==endx && y==endy) // 到达终点 
	{
		minn=min(minn,t); //更新最短时间 
		return ;
	}
	for(int i=0;i<4;i++) // 4个方向 
	{
		int dx=x+d[i][0];
		int dy=y+d[i][1];
		if(dx>=1 && dx<=n && dy>=1 && dy<=m && ch[dx][dy]!='K' && !vis[dx][dy]) //坐标合法,不是陷阱 没来过 
		{
			vis[dx][dy]=true;//标记 
			if(ch[dx][dy]=='#') t++; //破墙壁 时间加1 
			dfs(dx,dy,t+1);	//从当前为位置继续搜索 
			vis[dx][dy]=false; //回溯 
		}
	}
}

int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>ch[i][j];
			if(ch[i][j]=='S') //记录起点位置 
			{
				starx=i;
				stary=j;
			}
			if(ch[i][j]=='T')//记录终点位置 
			{
				endx=i;
				endy=j;
			}
		}
	}
	vis[starx][stary]=true;//起点提前做好标记 
    dfs(starx,stary,0);//从起点开始搜索 当前时间0 
    
    if(minn!=0x3f)  cout<<minn<<endl; // 输出 
    else cout<<"-1"<<endl; //无法到达 
	return 0; 
}

6、素数环

#include <bits/stdc++.h>
using namespace std; 
int a[15];
bool p[21],vis[15];
int n,cnt;

void print() //输出函数 
{
	cout<<++cnt<<":";
	for(int i=1;i<=n;i++)
	{
		if(i!=1) cout<<" ";
		cout<<a[i];
	}
	cout<<endl;
}

void check()//质数筛(质数标记为false) 
{
	p[1]=true;
	for(int i=2;i<=20;i++)
	{
		for(int j=2;j<=20/i;j++)
		{
			p[i*j]=true;
		}
	}
}

void dfs(int m) //可爱的小搜搜 
{
	if(m==n+1) //边界:前n个数已确定 
	{
		if(!p[a[m-1]+a[1]]) //最后一个数与第一个数之和为质数 
		{
			print(); //哇!找到一个方案了啊,调用输出函数 
		}
		return ;
	}
	
	for(int i=1;i<=n;i++) //遍历每一个数 
	{
		
		if(!vis[i]) //你是i吗?你之前没被用过啊,先备用 
		{
			if(m==1 || !p[i+a[m-1]]) //确定第一个数 无限制 或 i与前面相邻的数之和为素数 
			{
				a[m]=i; // 恭喜你i,你被选中了,可以作为素数环的第m个数 
				vis[i]=true;//标记 
				dfs(m+1);//小搜搜,开始下一个吧!
				vis[i]=false;//回溯 
			}
		}
	}
}

int main()
{
	cin>>n;
	
	if(n%2==1) //优化1:若n为奇数,不可能组成素数环 
	{
		cout<<"total:"<<cnt<<endl;
		return 0;
	}
	check();//优化2:先通过质数筛把质数保存下来 

	dfs(1); //从第一个数开始展开 
	cout<<"total:"<<cnt<<endl; //输出方案 
	return 0 ; 
}

7、素数环2

#include <bits/stdc++.h>
using namespace std; 
int a[22];
bool p[55],vis[22];
int n,cnt;

void print() 
{
	for(int i=1;i<=n;i++)
	{
		if(i!=1) cout<<" ";
		cout<<a[i];
	}
	cout<<endl;
}

void check()
{
	p[1]=true;
	for(int i=2;i<=2*n;i++)
	{
		for(int j=2;j<=2*n/i;j++)
		{
			p[i*j]=true;
		}
	}
}

void dfs(int m) 
{
	if(m==n+1) 
	{
		if(!p[a[m-1]+a[1]]) 
		{
			cnt++;
			print(); 
			if(cnt==10) exit(0);
		}
		return ;
	}
	
	for(int i=2;i<=n;i++) 
	{
		if(!vis[i]) 
		{
			if(!p[i+a[m-1]]) 
			{
				a[m]=i; 
				vis[i]=true;
				dfs(m+1);
				vis[i]=false;
			}
		}
	}
}

int main()
{
	cin>>n;
	
	if(n%2==1)   return 0;
	check();
	a[1]=1;
	
	dfs(2);
	return 0 ; 
}

8、子集和求解

#include <iostream>
#include <iomanip>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
vector<int> a,s;
bool vis[7010];
int n,k,cnt;
void dfs(int m,int ans)
{
	if(m>=n || ans>k) return ; //边界 
	
	if(ans==k) //子集和等于k 
	{
		cnt++; //方案数 
		for(int i=0;i<s.size();i++) //输出 
		{
			cout<<s[i]<<" ";
		}
		cout<<endl;
		if(cnt==1) exit(0); //输出第一种方案,直接结束程序 
	}
	
	for(int i=m;i<a.size();i++) // 遍历每一个数 
	{
		if(vis[i] || ans+a[i]>k) continue; //已用过 加上当前数已经大于k 直接结束当前循环 
		vis[i]=true;//标记 
		s.push_back(a[i]); //插入s数组 
		dfs(m+1,ans+a[i]);//搜索下一个 
		vis[i]=false;//回溯 
		s.pop_back();
	}
}

int main()
{
	cin>>n>>k;
	int sum=0;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		a.push_back(x);
		sum+=x;
	}

	if(k>sum) //优化:总和比k还要小 无法实现 
	{
		cout<<"No Solution!"<<endl;
		return 0;
	}
	
	dfs(0,0);
	cout<<"No Solution!"<<endl;
    return 0;
}

9、单词接龙

单词接龙

10、湖计数
【题解】DFS判连通块问题,也可以用BFS来写

#include<iostream>
#include<cstdio>
using namespace std;
int fxx[9]={0,-1,-1,-1,0,0,1,1,1};//x方向
int fxy[9]={0,-1,0,1,-1,1,-1,0,1};//y方向
int n,m,ans;
char a[105][105];
void dfs(int x,int y)
{
    int r,c;
    a[x][y]='.';
    for (int i=1;i<=8;i++)
    {
        r=x+fxx[i];
        c=y+fxy[i];
        if (r<1||r>n||c<1||c>m||a[r][c]=='.')//判断是否出界
            continue;
        a[r][c]='.';
        dfs(r,c);
    }
}
int main()
{
    scanf("%d %d\n",&n,&m);
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
            cin>>a[i][j];
    }
    ans=0;
    for (int i=1;i<=n;i++)
    {
        for (int j=1;j<=m;j++)
        {
            if (a[i][j]=='W')
            {
                ans++;
                dfs(i,j);
            }
        }
    }
    printf("%d\n",ans);
    return 0;
}

【后续提供视频讲解和标程】

前面课程连接
1、宽度优先搜索
2、深度优先搜索
3、回溯法-排列组合类
4、回溯法-切割问题与子集问题
5、回溯法-棋盘类问题

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

搜索题目综合 的相关文章

  • BASIC 中的 C 语言中的 PeekInt、PokeInt、Peek、Poke 等效项

    我想知道该命令的等效项是什么Peek and Poke 基本和其他变体 用 C 语言 类似PeekInt PokeInt 整数 涉及内存条的东西 我知道在 C 语言中有很多方法可以做到这一点 我正在尝试将基本程序移植到 C 语言 这只是使用
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 编译时展开 for 循环内的模板参数?

    维基百科 here http en wikipedia org wiki Template metaprogramming Compile time code optimization 给出了 for 循环的编译时展开 我想知道我们是否可以
  • 在 WPF 中使用 ReactiveUI 提供长时间运行命令反馈的正确方法

    我有一个 C WPF NET 4 5 应用程序 用户将用它来打开某些文件 然后 应用程序将经历很多动作 读取文件 通过许多插件和解析器传递它 这些文件可能相当大 gt 100MB 因此这可能需要一段时间 我想让用户了解 UI 中发生的情况
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • 类型或命名空间“MyNamespace”不存在等

    我有通常的类型或命名空间名称不存在错误 除了我引用了程序集 using 语句没有显示为不正确 并且我引用的类是公共的 事实上 我在不同的解决方案中引用并使用相同的程序集来执行相同的操作 并且效果很好 顺便说一句 这是VS2010 有人有什么
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • fastx常用控件

    目录 表格控件 bootstrap table 日历控件 bootstrap datepicker 通用帮助框 单选 多选 bootstrap标签页 通过设置数据字典来设置下拉框的值 表格控件 bootstrap table 自带搜索框 等
  • c++文件读写操作

    1 声明头文件 include 2 实例化对象 ifstream fin ifstream是中的一个类 fin是一个实例化对象 之所以起这个名字是类比cin 实际上他们有很多相似的地方 3 fin open 文件名 打开方式 本文的打开方式
  • 【机器视觉】——裂纹检测笔记

    目录 传统算法处理裂缝的基本思路 第一种思路 第二种思路 第三种思路 CPP代码 halcon代码 python代码 Matlab代码 深度学习缺陷检测 裂缝检测文献 传统算法处理裂缝的基本思路 第一种思路 1 先转换彩色图为灰度图 2 进
  • MySQL 8.0 隐藏索引

    隐式索引 最明显的一个作用类似 索引回收站 例如数据库长时间运行后 会积累很多索引 做数据库优化时 想清理掉没什么用的多余的索引 但可能删除某个索引后 数据库性能下降了 发现这个索引是有用的 就要重新建立 对于较大的表来说 删除 重建索引的
  • python筑基——基础知识作业汇总,学习笔记

    作业一 语法 变量 输 输出 基本运算 基本数据类型 字符串 类型转换 1 计算整型50乘以10再除以5的商并使用print输出 result 50 10 5 print result 2 判断整型8是否大于10的结果并使用print输出
  • codeforces 825 E Minimal Labels

    Problem codeforces com contest 825 problem E Reference 看第 5 条评论 Meaning 给出一个n个结点的DAG 找一个给结点编号的序列 且满足3个条件 编号为 1 n 每个编号出现且
  • 第三章:Linux环境基础开发工具使用

    系列文章目录 文章目录 系列文章目录 前言 一 yum 1 三板斧 2 扩展 3 软件包名称 二 vim 1 vim基本模式 2 vim基本操作 插入模式 命令模式 底行模式 注释 三 gcc g 1 预处理 2 编译 3 汇编 4 链接
  • Python opencv 机器学习 2.knn k近邻 ocr识别数字 使用digits.png(opencv自带)

    import cv2 import numpy as np from matplotlib import pyplot as plt 识别数字OCR img cv2 imread digits png gray cv2 cvtColor i
  • 见习网工之综合实验

    需求一 信息中心配置Eth trunk实现链路冗余 SW1 interface Eth Trunk1 mode lacp static least active linknumber 1 trunkport GigabitEthernet
  • 【每日一练】在JSX中使用条件渲染

    条件渲染 技术方案 三元表达式 逻辑 运算 1 三元表达式 满足条件才渲染一个span标签 const flag true function App return div flag div h1 span 我是JackWoot span h
  • 自动化测试如何做?接口自动化测试如何才能做好?

    前言 接口自动化测试常用框架 Python requests pytest yaml alluer Jenkins 接口自动化测试的目的 自动化测试的主要目的是用来回归测试的 当代码有变化时 有可能影响不应该变化的逻辑 这个时候为了确认这种
  • There was a problem importing one of the Python modules required to run yum

    为什么80 的码农都做不了架构师 gt gt gt 最近从python 2 6 升级到python2 7 导致 yum 不可用 原因主要是yum 不支持python27 因此需要更改yum的可用路径 which yum 查看下yum的安装路
  • js拖拽实现

  • 强化学习的A3C算法应用(训练Atari游戏)

    A3C算法的全称是Asynchronous Advantage Actor Critic 异步优势执行者 评论者算法 这个算法和优势执行者 评论者算法的区别在于 在执行过程中不是每一步都更新参数 而是在回合结束后用整个轨迹进行更新 因此可以
  • 多个git合并,并保留log历史记录

    面临的需求是 将多个git仓库作为一个单独目录 整合到一个新的git仓库中 并且保留历史记录 1 新建一个summary仓库 新建一个summary仓库 用于整合一系列git仓库 git clone
  • openwrt编译x86固件

    x86 openwrt固件编译 2017年十月四日我在珠海 中秋之际写下这篇文章 祝各位看官花好月圆 有情人终成眷属 最近一直在玩Openwrt 以前上学的时候接触一丁丁 但是只限于烧写别人编译好的固件 这次要真刀实干了 学习了一周各种百度
  • 专访用自己姓氏命名编译器YC++的创始人

    在CSDN的论坛里看到了这样的一条帖子 请使用中国人开发的C C 编译器 网页浏览器内核 并提供了该软件的下载地址 从大家的跟帖来看很多人 是很有兴趣的 但是作者并没有留下太多的介绍说明类的文字 为了一探究竟 我拨通了作者留下的电话并完成了
  • Ubuntu 16.04设置root用户登录图形界面

    Ubuntu默认的是root用户不能登录图形界面的 只能以其他用户登录图形界面 这样就很麻烦 因为权限的问题 不能随意复制删除文件 用gedit编辑文件时经常不能保存 只能用vim去编辑 下面以Ubuntu 16 04版为例说明 1 打开终
  • STM32实战项目:HAL_RCC_OscConfig中程序卡死问题解决办法

    STM32实战项目经验 HAL RCC OscConfig中程序卡死问题解决办法 工程环境 STM32CUBEIDE STM32F405VG 现象复现 项目中一个是IAP程序 另一个是APP程序 两个程序都是使用STM32CubeIDE生成
  • 搜索题目综合

    BFS 1 小X学游泳 题解 枚举每一个点作为连通块的起点 求得连通块大小 然后打擂台求最值即可 参考代码 include