zoukankan      html  css  js  c++  java
  • 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 }

    感谢你的观赏!!!

  • 相关阅读:
    【Delphi】MD5算法(二):应用
    迅雷不能下载FlashPlayer,下载后自动删除,狂汗!!!
    工作笔记1
    GridControl 获取筛选后的数据{笔记}
    Invoke与BeginInvoke[转]
    这几项能力不知道要几年
    你永远不要去做的事1【译】
    window环境变量——心得【转】
    刚做好的网站客服系统,欢迎大家测试
    .Net 2.0里有一个有用的新功能:迭代器
  • 原文地址:https://www.cnblogs.com/jackes/p/1996449.html
Copyright © 2011-2022 走看看