• POJ3083Children of the Candy Corn


    转载请注明出处:優YoU http://user.qzone.qq.com/289065406/blog/1303432339

     

    题目大意:

    给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走

    先输出左转优先时,从SE的步数

    再输出右转优先时,从SE的步数

    最后输出SE的最短步数

     

    W为宽,列数

    H为高,行数

     

    解题思路:

    DFSBFS的综合题水题,难度不大,但是写代码时要注意几方面:

     

    1、 左转、右转优先搜索时必须标记当前位置时的方向,我定义的方向是

        


     

    最初的方向由起点S确定,而下一步的方向则由前一步的走向决定

     

    例如 左边优先搜索:

    当前位置的方向指向 1(向左),(这同时说明前一步是在第“3”的位置走过来的)

    那么走下一步时,就要根据2103的顺序,先逐格确定当前位置周边的四格是否可行

    若第一次确认2可行,就走到2,在位置2时的方向为2(向下)

    2不可行,则再确定1,若1可行,就走到1,在位置1时的方向为1(向左)

      1也不可行,则再确定0,若0可行,就走到0,在位置0时的方向为0(向上)

      0也不可行,说明进入了迷宫的死胡同,要从原路返回,走回3

     

    右边优先搜索也同理。

     

    根据我定义的方向,设当前位置为d,那么

    左转,用数学式子表达就是  d=(d+1)%4

    右转,用数学式子表达就是  d=(d+3)%4

    我比较懒,在我的程序中,DFSBFS都用了多入口的做法,有兴趣的同学可以利用我给出的这两个式子对代码进行优化。

            

    这里有一点必须要注意的:

    左边、右边优先搜索都不是找最短路,因此走过的路可以再走,无需标记走过的格

     

    2、 寻找最短路只能用BFS

    因此在做第3问时别傻乎乎的又用DFSDFS对于样例的输入确实和BFS得到的结果一样的,别以为样例PASS就提交了。。。所以我就说样例没代表性,学会测试数据很重要= =

     

    注意有一点:

    要求E的最短路,必须把迷宫模拟为树,S为根,找到E所在的层(树深),该层就是SE的最短路,处理技巧就是在BFS时,令queue[tail]depth等于对应的queue[head]depth+1,详细见我的程序

    把循环的次数作为深度就铁定错的

      1 //Memory Time 
    2 // 212K 0MS
    3
    4 #include<iostream>
    5 using namespace std;
    6
    7 typedef class
    8 {
    9 public:
    10 int r,c;
    11 int depth;
    12 }SE;
    13
    14 SE s,e; //起止点
    15 int Lstep; //左边优先搜索 时从S到E的总步数
    16 int Rstep; //右边优先搜索 时从S到E的总步数
    17 int shortstep; //S到E的最少总步数
    18
    19 bool maze[41][41]; //记录迷宫的“可行域”与“墙”
    20
    21 void DFS_LF(int i,int j,int d) //左边优先搜索,i,j为当前点坐标,d为当前位置方向
    22 {
    23 Lstep++;
    24 if(i==e.r && j==e.c)
    25 return;
    26
    27 switch(d)
    28 {
    29 case 0:
    30 {
    31 if(maze[i][j-1])
    32 DFS_LF(i,j-1,1);
    33 else if(maze[i-1][j])
    34 DFS_LF(i-1,j,0);
    35 else if(maze[i][j+1])
    36 DFS_LF(i,j+1,3);
    37 else if(maze[i+1][j])
    38 DFS_LF(i+1,j,2);
    39 break;
    40 }
    41 case 1:
    42 {
    43 if(maze[i+1][j])
    44 DFS_LF(i+1,j,2);
    45 else if(maze[i][j-1])
    46 DFS_LF(i,j-1,1);
    47 else if(maze[i-1][j])
    48 DFS_LF(i-1,j,0);
    49 else if(maze[i][j+1])
    50 DFS_LF(i,j+1,3);
    51 break;
    52 }
    53 case 2:
    54 {
    55 if(maze[i][j+1])
    56 DFS_LF(i,j+1,3);
    57 else if(maze[i+1][j])
    58 DFS_LF(i+1,j,2);
    59 else if(maze[i][j-1])
    60 DFS_LF(i,j-1,1);
    61 else if(maze[i-1][j])
    62 DFS_LF(i-1,j,0);
    63 break;
    64 }
    65 case 3:
    66 {
    67 if(maze[i-1][j])
    68 DFS_LF(i-1,j,0);
    69 else if(maze[i][j+1])
    70 DFS_LF(i,j+1,3);
    71 else if(maze[i+1][j])
    72 DFS_LF(i+1,j,2);
    73 else if(maze[i][j-1])
    74 DFS_LF(i,j-1,1);
    75 break;
    76 }
    77 }
    78
    79 return;
    80 }
    81
    82 void DFS_RF(int i,int j,int d) //右边优先搜索,i,j为当前点坐标,d为当前位置方向
    83 {
    84 Rstep++;
    85 if(i==e.r && j==e.c)
    86 return;
    87
    88 switch(d)
    89 {
    90 case 0:
    91 {
    92 if(maze[i][j+1])
    93 DFS_RF(i,j+1,3);
    94 else if(maze[i-1][j])
    95 DFS_RF(i-1,j,0);
    96 else if(maze[i][j-1])
    97 DFS_RF(i,j-1,1);
    98 else if(maze[i+1][j])
    99 DFS_RF(i+1,j,2);
    100 break;
    101 }
    102 case 1:
    103 {
    104 if(maze[i-1][j])
    105 DFS_RF(i-1,j,0);
    106 else if(maze[i][j-1])
    107 DFS_RF(i,j-1,1);
    108 else if(maze[i+1][j])
    109 DFS_RF(i+1,j,2);
    110 else if(maze[i][j+1])
    111 DFS_RF(i,j+1,3);
    112 break;
    113 }
    114 case 2:
    115 {
    116 if(maze[i][j-1])
    117 DFS_RF(i,j-1,1);
    118 else if(maze[i+1][j])
    119 DFS_RF(i+1,j,2);
    120 else if(maze[i][j+1])
    121 DFS_RF(i,j+1,3);
    122 else if(maze[i-1][j])
    123 DFS_RF(i-1,j,0);
    124 break;
    125 }
    126 case 3:
    127 {
    128 if(maze[i+1][j])
    129 DFS_RF(i+1,j,2);
    130 else if(maze[i][j+1])
    131 DFS_RF(i,j+1,3);
    132 else if(maze[i-1][j])
    133 DFS_RF(i-1,j,0);
    134 else if(maze[i][j-1])
    135 DFS_RF(i,j-1,1);
    136 break;
    137 }
    138 }
    139 return;
    140 }
    141
    142 void BFS_MSS(int i,int j) //最短路搜索
    143 {
    144 bool vist[41][41]={false};
    145 SE queue[1600];
    146 int head,tail;
    147
    148 queue[head=0].r=i;
    149 queue[tail=0].c=j;
    150 queue[tail++].depth=1; //当前树深标记,这是寻找最短路的关键点
    151
    152 vist[i][j]=true;
    153
    154 while(head<tail)
    155 {
    156 SE x=queue[head++];
    157
    158 if(x.r==e.r && x.c==e.c)
    159 {
    160 cout<<x.depth<<endl;
    161 return;
    162 }
    163
    164 if(maze[x.r][x.c-1] && !vist[x.r][x.c-1])
    165 {
    166 vist[x.r][x.c-1]=true;
    167 queue[tail].r=x.r;
    168 queue[tail].c=x.c-1;
    169 queue[tail++].depth=x.depth+1;
    170 }
    171 if(maze[x.r-1][x.c] && !vist[x.r-1][x.c])
    172 {
    173 vist[x.r-1][x.c]=true;
    174 queue[tail].r=x.r-1;
    175 queue[tail].c=x.c;
    176 queue[tail++].depth=x.depth+1;
    177 }
    178 if(maze[x.r][x.c+1] && !vist[x.r][x.c+1])
    179 {
    180 vist[x.r][x.c+1]=true;
    181 queue[tail].r=x.r;
    182 queue[tail].c=x.c+1;
    183 queue[tail++].depth=x.depth+1;
    184 }
    185 if(maze[x.r+1][x.c] && !vist[x.r+1][x.c])
    186 {
    187 vist[x.r+1][x.c]=true;
    188 queue[tail].r=x.r+1;
    189 queue[tail].c=x.c;
    190 queue[tail++].depth=x.depth+1;
    191 }
    192 }
    193 return;
    194 }
    195
    196 int main(int i,int j)
    197 {
    198 int test;
    199 cin>>test;
    200 while(test--)
    201 {
    202 int direction; //起点S的初始方向
    203 int w,h; //size of maze
    204 cin>>w>>h;
    205
    206 /*Initial*/
    207
    208 Lstep=1;
    209 Rstep=1;
    210 memset(maze,false,sizeof(maze));
    211
    212 /*Structure the Maze*/
    213
    214 for(i=1;i<=h;i++)
    215 for(j=1;j<=w;j++)
    216 {
    217 char temp;
    218 cin>>temp;
    219 if(temp=='.')
    220 maze[i][j]=true;
    221 if(temp=='S')
    222 {
    223 maze[i][j]=true;
    224 s.r=i;
    225 s.c=j;
    226
    227 if(i==h)
    228 direction=0;
    229 else if(j==w)
    230 direction=1;
    231 else if(i==1)
    232 direction=2;
    233 else if(j==1)
    234 direction=3;
    235 }
    236 if(temp=='E')
    237 {
    238 maze[i][j]=true;
    239 e.r=i;
    240 e.c=j;
    241 }
    242 }
    243
    244 /*Left First Search*/
    245
    246 switch(direction)
    247 {
    248 case 0: {DFS_LF(s.r-1,s.c,0); break;}
    249 case 1: {DFS_LF(s.r,s.c-1,1); break;}
    250 case 2: {DFS_LF(s.r+1,s.c,2); break;}
    251 case 3: {DFS_LF(s.r,s.c+1,3); break;}
    252 }
    253 cout<<Lstep<<' ';
    254
    255 /*Right First Search*/
    256
    257 switch(direction)
    258 {
    259 case 0: {DFS_RF(s.r-1,s.c,0); break;}
    260 case 1: {DFS_RF(s.r,s.c-1,1); break;}
    261 case 2: {DFS_RF(s.r+1,s.c,2); break;}
    262 case 3: {DFS_RF(s.r,s.c+1,3); break;}
    263 }
    264 cout<<Rstep<<' ';
    265
    266 /*Most Short Step Search*/
    267
    268 BFS_MSS(s.r,s.c);
    269
    270 }
    271 return 0;
    272 }
  • 相关阅读:
    HDFS、YARN、Mapreduce简介
    List<object> 转 List<T>
    CTR+A组合键 以及终止按键事件传递
    BackgroundWorker 的输入、输出参数、进度条与文字刷新、取消机制、返回事件
    读取Excel文件的两种方法比较 以及用NPOI写入Excel
    浅复制不能传递,重新赋值就重新浅复制
    gridControl添加右键菜单
    C#设置Excel行高、列宽
    任意字符串(包括空串)都包含空白字符串
    JAVA 在程序中存储和修改信息
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2122369.html
Copyright © 2020-2023  润新知