hdoj 1010 迷宫问题--回溯法 dfs也行 判断a是否能到b点

思想1:电脑就是一个有特性(很有耐心)的小孩,作为编程人员应该站在它的角度考虑问题,编程就是用一种特定的编程语言跟它交流。

思想2:站在编程员得角度思考,数学是电脑的神经,数学思维是他的灵魂,数学知识是他的身体,知识是有体系的,他有自己独有的性质、属性、规律,编程人员就是用一种特定的编程语言依据他独有的知识、属性、规律进行有规律的不断的推理,直到到达目标,而这目标和知识以及他的一些性质都是由现实生活中一些实际问题,经过分块简化抽象,数学模型抽象而来。

算法核心:回溯在现实生活中就是一种试探的尝试,例如,你很久以前去过一个地方,只很清楚记得目的地的一个特征(假设到时你能知道),现在你在一个十字路口,不知哪个方向是目的地所在的方向,那就只能选择一个方向进行试探,如果运气不好的话,错了,就只能回到十字路口,在进行下一个方向的尝试,这个回到十字路口就是一种回溯。

算法具体描述:结合迷宫问题分析,

现实问题简化抽象:电脑是一个小孩在这个问题中就是只知道往四个方向(上、下、左、右)走,能够分辨越界,开始,结束,通路,墙壁。能否M步从开始到结束。

数学模型抽象:用S代表开始位置,D代表结束位置,X代表墙壁,‘.’代表通路,i代表行坐标,j就代表列坐标,n(0)代表行坐标的最大值(最小值),m(0)就代表列坐标最大值(最小值),(i+1,j)代表向下走一步,(i,j+1)代表向右走一步,(i-1,j)代表向上走一步,(i,j-1)代表向左走一步,当i>n或j>m或i<0或j<0是代表越界。

编程语言抽象:包括三个方面,

      1,数据结构(知识)。

        一个二维的字符数组s[10][10]代表整个迷宫。s[i+1][j]代表先下走一步,s[i-1][j]代表向上走一步,s[i][j-1]代表向左走一步,s[i][j+1]代表向右走一步。

s[i][j]=S代表起始位置,s[i][j]=D代表结束位置,s[i][j]=X代表墙壁位置,s[i][j]=‘.’代表通路位置,

      2,操作(性质 属性 规律)。

        s[10][10]每次只能向上、下、左、右移动一步。只能从S位置开始,D位置结束。X位置不能经过。

      3,目标。

        判读是否存在s[i][j]从S位置到D位置经过的通路个数是否等于M。

编程实现要点:

      1,标记。经过的位置s[i][j]=X。

      2,剪纸(重点)。

      3,判断结束的标记。

源代码:

1 #include <iostream>
2 #include <string.h>
3 #include <cmath>
4 usingnamespace std;
5
6 char s[10][10];
7 int scx,scy,oux,ouy,sum,n,m,l,flag;
8 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
9
10 void back(int x,int y,int step)
11 {
12 int ecx,ecy,i;
13 if(x==oux&&y==ouy&&step==l)
14 flag=1;
15 if(flag)
16 return ;
17 if(step>l)
18 return ;
19 if(sum+1<l-step)
20 return ;
21 for(i=0;i<4;i++)
22 {
23 ecx=x+dir[i][0];
24 ecy=y+dir[i][1];
25 if(s[ecx][ecy]!='X'&&ecx>=0&&ecy>=0&&ecx<n&&ecy<m)
26 {
27 s[ecx][ecy]='X';
28 sum--;
29 back(ecx,ecy,step+1);
30 s[ecx][ecy]='.';
31 sum++;
32 }
33 }
34 }
35
36 int main()
37 {
38 int i,j;
39 while(cin>>n>>m>>l,m+n+l)
40 {
41 sum=0;
42 for(i=0;i<n;i++)
43 scanf("%s",s[i]);
44 for(i=0;i<n;i++)
45 for(j=0;j<m;j++)
46 {
47 if(s[i][j]=='D')
48 {
49 oux=i;
50 ouy=j;
51 }elseif(s[i][j]=='S')
52 {
53 scx=i;
54 scy=j;
55 }elseif(s[i][j]=='.')
56 sum++;
57 }
58 if(sum+1<l)
59 {
60 cout<<"NO"<<endl;
61 continue;
62 }
63 if((abs(oux-scx)+abs(ouy-scy))%2!=l%2)
64 {
65 cout<<"NO"<<endl;
66 continue;
67 }
68 flag=0;
69 s[scx][scy]='X';
70 back(scx,scy,0);
71 if(flag)
72 {
73 cout<<"YES"<<endl;
74 }
75 else
76 {
77 cout<<"NO"<<endl;
78 }
79 }
80 return0;
81 }

感谢你的观赏!!!

posted @ 2011-03-26 18:26  shijiwomen  阅读(902)  评论(0编辑  收藏  举报