主页 > 程序人生 > 用栈模拟深度优先搜索

用栈模拟深度优先搜索

题目原型来自HDUOJ的1372 Knight Moves
很简单的一个搜索题
就是告诉你棋盘上的两个点,然后让你算出Knight,也就是国际象棋的马,最少多少步能够从一个点到另一个点。
算法很简单,深搜即可,这个不是本文讨论的问题。这里我是把原来通过函数递归调用的深搜改为用栈自行模拟
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include<stdio.h>
#include<stack>
using namespace std;
#define INF	99999
int map[8][8];
int dir[8][2]={{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
struct node{
	int x,y,t;
};
stack<node>zerob;
int main()
{
    char str1[3],str2[3];
    node head,p;
	while(scanf("%s %s",str1,str2)==2)
    {
		for(int i=0;i<8;i++)
		{
			for(int j=0;j<8;j++)
			{
				map[i][j]=INF;
			}
		}
 
		while(!zerob.empty()){
			zerob.pop();
		}
		head.x=str1[0]-'a';
		head.y=str1[1]-'1';
		head.t=0;
		int ans=-1;
		zerob.push(head);
        while(!zerob.empty()){
			head=zerob.top();
			zerob.pop();
			if(head.x==str2[0]-'a'&&head.y==str2[1]-'1')
			{
				if(ans>head.t||ans==-1)
					ans=head.t;
 
				continue;
			}
			for(int i=0;i<8;i++)
			{
				p=head;
				p.x+=dir[i][0];
				p.y+=dir[i][1];
				if(!(p.x>=0 && p.x<8 && p.y>=0 && p.y<8))
					continue;
				p.t++;
				if(map[p.x][p.y]<=p.t)
					continue;
				map[p.x][p.y]=p.t;
				zerob.push(p);
			}
		}
        printf("To get from %s to %s takes %d knight moves.\n",str1,str2,ans);
    }
}

后记:
其实当你理解了深搜和广搜后,你会发现,你写出来的深搜和广搜的代码可以看上去是差不多的。为什么那么说呢,因为,无论那种搜索,都是通过对一个线性表进行处理,只不过是先处理头部还是尾部的问题罢了。处理头部优先的时候,就是广度优先了,因为,头部的都是兄弟节点;而尾部的则是深度优先,因为放入尾部的都是刚刚生产出来的节点——也就是所谓一条路走到死。
同理可以联想到启发式搜索。启发式搜索就是先以你自定义的优先级处理,然后再以广度为优先级处理。
所以,归根结底,所谓的搜索,就是一种定义了优先级的枚举。当然,这个只是我个人的理解,欢迎各位大牛拍转。

相关日志

, , , , ,

评论:2

参与评论
  1. 回复 南柯一梦
    10/03/31

    来看看,最近也要学习点算法了

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

引用:0

下面所列的是引用到本博客的链接
用栈模拟深度优先搜索 来自 混沌的云
顶部