搜索题目综合

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、回溯法-棋盘类问题

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

信奥教练Andy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值