搜索小结
基于贪心算法的初识与简单学习后,对搜索进行了认识与学习。
深度优先搜索(dfs)
基本模型
void dfs(int step)
{
//判断边界
//尝试每一种可能(扩展)
for (i=0 ; i<=n; i++)
{
//继续下一步
dfs(steo+1);
}
//返回
}
函数的参数是需要维护的值。
迷宫问题
典例:5*5的迷宫,1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走, 要求编程序找出从左上角到右下角的最短步数。
- Input
输入5行5列的迷宫。数据保证有唯一解。 - Output
左上角到右下角的最短路径,格式如样例所示。 - Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0 - Sample Output
9
核心操作:
void dfs(int x,int y,int step)
{
int next[4][2]={{0,1},
{1,0},
{0,-1},
{-1,0}};
int tx,ty,k;
if(x==4 && y==4)
{
min=step<min?step:min;
return://重要返回
}
for(k=0 ; k<=3 ; k++)
{
tx=x+next[k][0];
ty=y+next[k][1];
if(tx<0 || tx>4 || ty<0 || ty>4) continue;
if(a[x][y]=='0' && book[tx][ty]==0)
{
book[tx][ty]=1;
dfs(tx,ty,step+1);
book[tx][ty]=0;//取消标记
}
}
return;
}
广度优先搜索(bfs)
基本模型
void dfs(int x,int y)
{
//枚举方向(这里是二维的m*n地图)
int next[4][2]={{0,1},//右
{1,0},//下
{0,-1},//左
{-1,0}};//上
for(k=0 ; k<=3 ; k++)
{
//下一个结点的坐标
tx=x+next[k][0];
ty=y+next[k][1];
//判断越界
if(tx<0 || tx>n-1 || ty<0 || ty>m-1)//m,n为地图大小
continue;
//判断是否可走或走过
if(map[tx][ty]==/*可走标识*/ && book[tx][ty]==0)
{
book[tx][ty]=1;//标记走过
dfs(tx,ty);//尝试下一点
}
}
return;
}
迷宫问题(再)
用队列模拟,结构体实现。
struct note
{
int x;
int y;
int step;
}
int main()
{
struct note q[2501];
int head,tail,stx,sty,tx,ty,flag;
int map[5][5]={0};
int book[5][5]={0};
int next[4][2]={{0,1},
{1,0},
{0,-1},
{-1,0}};
head=1;
tail=1;
q[tail].x=stx;
q[tail].y=sty;
q[tail].step=0;
tail++;
book[stx][sty]=1;
flag=0;
while(head<tail)
{
for(k=0 ; k<=3 ; k++)
{
tx=q[head].x+next[k][0];
ty=q[head].y+next[k][1];
if(tx<0 || tx>4 || ty<0 || ty>4) continue;
if(map[x][y]=='0' && book[tx][ty]==0)
{
book[tx][ty]=1;
q[head].x=tx;
q[head].y=ty;
q[head].step=q[head].step+1;
tail++;
}
if(tx==4 && ty==4)
{
flag=1;
break;
}
}
if(flag) brak;
head++;
}
printf("%d",q[tail-1].step);
return 0;
}
迷宫问题(升级)
典例:5*5的迷宫,1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线,输出路线所经过的坐标。
- Input
输入5行5列的迷宫。数据保证有唯一解。 - Output
左上角到右下角的最短路径,格式如样例所示。 - Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0 - Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)
要求输出路径,加入一个栈,进行入栈出栈操作
//加入一个栈来存储路径
struct node
{
int x;
int y;
}s[100];
int top=0;
//在标记尝试后将尝试目标入栈
top++;
s[top].x=x;
s[top].y=y;
//在取消标记时将取消目标出栈
top--;