深搜
过程:
对每一个可能的分支路径深入到不能再深入为止。而且每个节点只能访问一次
【第一题:孙悟空找师傅】
问题描述:西游路上咱们的唐长老又一次被妖怪抓走了。已知妖怪洞穴是一个N*N 的正方形,其中有一些假山堵路。
输入:第一行是一个正整数N(2 输出:如果悟空和八戒可以救出师傅就输出YES,否则就输出NO。
样例输入:
4
0 0 0 0
0 1 0 1
1 0 0 1
1 1 0 2
样例输出:
YES
//递归的思想,在二维的数组里面遍历上下左右四个方向
#include
using namespace std;
/*
4
0 0 0 0
0 1 0 1
1 0 0 1
1 1 0 2
*/
//深搜,孙悟空在地图的左上角,师傅所在的地方为2,
//有石头的地方为1,有路的地方为0,,请输入一个n,以及地图
//寻找孙悟空是否能够找到师傅,可以输出YES,否则输出NO
int dx[5]={-1,0,1,0},dy[5]={0,1,0,-1};//控制搜索方向
//确保四个方向能够搜到
int G[105][105],vis[105][105]; //G存储地图,
//vis标记是否搜索过
int n;//n为地图的长和宽
bool f=false;//标记是否能够找到师傅
void dfs(int x,int y){//如果找到师傅则结束
if(G[x][y]==2){
cout<=0&&xx=0&&yy>n;
for(int i=0;i>G[i][j];
}
}
if(G[0][0]==1){
cout<<"NO"<
【第二题:传送门】
问题描述:
观音有一件法宝,叫做传送门,我们可以通过这件法宝从妖怪洞穴出去,了保密,观音把这件法宝放在了一个妖怪洞穴,我们只要找到那个洞穴就可以出去了。观音已经把放法宝洞穴的坐标告诉我了,我们需要编程确定一下是否能到达那个洞穴就行了。唐老大:空空,听紧箍咒和编程你选一个吧。空空:你.(吐血三升),你把样例先告诉我。
输入:第一行包含一个正整数N(1
输入:如果悟空他们可以成功走到传送门空间就输出YES,否则就输出 No。
样例输入:
5
1 0 0 1 0
1 1 1 1 1
1 0 1 0 0
1 0 1 1 1
0 1 0 1 0
4 4
2 1
样例输出:
YES
#include
using namespace std;
//输入一个地图,1为可走,0为不可走,下面输入孙悟空所在的坐标
//以及传送门所在的坐标,深度优先搜索看孙悟空是否能找到传送门
/*
输入:1
5
1 0 0 1 0
1 1 1 1 1
1 0 1 0 0
1 0 1 1 1
0 1 0 1 0
4 4
2 1
输出:
YES
*/
int dx[5]={-1,0,1,0},dy[5]={0,1,0,-1};//遍历方向
int n;//存储地图
int G[1001][1001],vis[1001][1001];//G存储地图,vis标记是否被搜索过
bool f=false;//存储是否找到传送门
int sx,sy,cx,cy;
void dfs(int x,int y){
if(x==cx&&y==cy){
cout<<"YES"<=1&&xx<=n&&yy>=1&&yy<=n&&G[xx][yy]!=0&&vis[xx][yy]==0){
vis[xx][yy]=1;
dfs(xx,yy);
vis[xx][yy]=0;
}
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
cin>>G[i][j];
}
}
cin>>sx>>sy;
cin>>cx>>cy;
if(sx==cx&&cy==sy){
cout<<"YES"<
【题目三:西游记之海域分块】
问题描述:
最近天气炎热,人鱼王国水位下降陆地露出海面,把王国分成了几个部分,国王的命令无法传达给公民,让红烧鱼国王感觉非常苦恼,所以国王想要请悟空帮忙给各个水域传递一个消息。虽然人鱼王国不大,但是如果悟空每个地方都去一次就会耽误很长时间,影响取经大业,所以悟空决定先计算一下陆地把人鱼王国分成了几部分。输入:第一行包合两个正整数N和M(1
样例输入:
5 5
1 0 0 1 0
0 1 0 0 1
1 0 1 0 0
1 0 0 1 1
0 1 0 1 0
样例输出:
6
核心思路:
从第一行开始从左向右开始遍历,如果当前位置是0,就从当前位置开始向四周深搜,把相连的0都变成1
#include
using namespace std;
/*
输入:第一行包含两个正整数N和M表示人鱼王国的长和宽 ,下面是一个
N行M列的二维数组,其中1表示陆地,0表示海水
输出:一个整数a表示陆地把海域分成的份数(斜着方向不算通)
样例输入:
5 5
1 0 0 1 0
0 1 0 0 1
1 0 1 0 0
1 0 0 1 1
0 1 0 1 0
样例输出:
6
*/
//核心思路:从第一行开始,从左向右开始遍历,如果当前位置是0,
//就从当前位置开始向四周深搜,把相连的 0都变成 1
int n,m;
int G[1001][1001];
int dx[5]={1,0,-1,0},dy[5]={0,1,0,-1};
void dfs(int x,int y){
for(int i=0;i<4;i++){
int xx=x+dx[i];
int yy=y+dy[i];
if(xx>=0&&xx=0&&yy>n>>m;
for(int i=0;i>G[i][j];
}
}
int res=0;
for(int i=0;i
【题目三: 国王的神器 】
问题描述:
红烧鱼国王拿出了祖传神器(水管),他可以使斜对角的海域连通,这样悟空就可以少通知一些地方了,真是个不错东西,我们-起来计算一下使用神器后,悟空需要通知几个海域。
输入:第一行包含两个正整数N和M(1 一个N行M列的二维数组,其中1表示陆地,0表示海水。
输入:一个整数a表示陆地把海域分成的份数(斜着方向连通)。
样例输入:
5 5
1 0 0 1 0
0 1 0 0 1
1 0 1 0 0
1 0 0 1 1
0 1 0 1 0
样例输出:
2
#include
using namespace std;
/*
5 5
1 0 0 1 0
0 1 0 0 1
1 0 1 0 0
1 0 0 1 1
0 1 0 1 0
*/
int G[1001][1001];
int n,m,mins=2147483647,sum=0;
int dx[5]={0,1,0,-1},dy[5]={1,0,-1,0};
void dfs(int x,int y){
for(int dx=-1;dx<=1;dx++){
for(int dy=-1;dy<=1;dy++){
int xx=x+dx;
int yy=y+dy;
if(xx>=1&&xx<=n&&yy>=1&&yy<=m&&G[xx][yy]==0){
G[xx][yy]=1;
dfs(xx,yy);
}
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>G[i][j];
}
}
int res=0;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(G[i][j]==0){
if(G[i][j]==0){
G[i][j]=1;
dfs(i,j);
res++;
}
}
}
}
cout<
广搜
特点:
BFS是从进到远搜索的,因此通常可以利用BFS来搜索最短的步数
搜索过程:
首先需要把起点给压到队列里面去,接着每一轮判断队列是否为空,如果为空则结束BFS,不为空则取出队首元素a,将所有与a相邻的点判断是否被访问过,如果没有就压进队列中。(按层遍历,找到即最优,并且通常需要通过队列来实现)
#include
using namespace std;
/*
5 4
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 1
0 0 0 1
1 1 4 3
*/
int map[51][51],book[51][51];//map存储地图,book存储是否被标记过
int m,n,sx,sy,p,q,tx,ty;//m行n列sx,sy表示悟空的坐标,p,q表示师傅所在的坐标
//tx和ty记录中间步骤坐标
int head=1,tail=1,flag=0;//head表示队首,tail表示队尾,flag标记是否找到师傅
int nt[4][2]={{-1,0},{0,1},{1,0},{0,-1}};//遍历上下左右四个方向
struct node{
int x,y,step;
}que[2501];//定义结构体数组存储当前搜索的x和y以及步数
void bfs(){
//记录起点位置
que[tail].x=sx;
que[tail].y=sy;
que[tail].step=0;
tail++;//队尾后移
book[sx][sy]=1;//标记已走过
//开始循环搜索
while(headm||ty>n) continue;
//判断该坐标是否可走
if(map[tx][ty]==0&&book[tx][ty]==0){
book[tx][ty]=1;//标记已经走过
//当前点入队
que[tail].x=tx;
que[tail].y=ty;
que[tail].step=que[head].step+1;
tail++; //队尾后移
}
}
//判断是否可以找到师傅
if(tx==p&&ty==q){//成功找到师傅
flag=1;
break;
}
if(flag) break;//找到师傅,停止搜索
head++;//队首后移,继续搜索
}
}
int main(){
cin>>m>>n;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
cin>>map[i][j];
}
}
cin>>sx>>sy>>p>>q;
bfs();
cout<