POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

Posted Amysear

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE相关的知识,希望对你有一定的参考价值。

POJ 3083 -- Children of the Candy Corn(DFS+BFS)

题意:

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

1)先输出左转优先时,从S到E的步数

2)再输出右转优先时,从S到E的步数

3)最后输出S到E的最短步数

 

解题思路:

前两问DFS,转向只要控制一下旋转方向就可以

首先设置前进方向对应的数字

向上——N——0

向右——E——1

向下——S——2

向左——W——3

比如说右转优先,即为向右,向前,向左,向后,即逆时针方向for(int i=1;i>=-2;i--)

左转优先,即为向左,向前,向右,向后,即顺时针方向for(int i=-1;i<=3;i++)

第三问最短路,BFS

普通递归(TLE)

  1 #include<iostream>
  2 #include<cstring>
  3 #include<queue>
  4 #include<cstdio>
  5 using namespace std;
  6 int r,c;///行r,列c
  7 int r0,c0,r3,c3;///r0,c0用来标记入口,r3,c3用来标记出口
  8 const char *dirs = "NESW";
  9 const int maxn = 41;
 10 char square[maxn][maxn];
 11 const int dr[] = {-1,0,1,0};
 12 const int dc[] = { 0,1,0,-1};
 13 struct node{
 14 int row,col,deep;
 15 int dir;///0123对应NESW
 16 node(int row=0,int col=0,int dir=0,int deep=0):row(row),col(col),dir(dir),deep(deep){}
 17 };
 18 bool inside(int xx,int yy)
 19 {
 20     return xx>=1 && xx<=r && yy>=1 && yy<=c;
 21 }
 22 
 23 bool flag1;
 24 int step1;
 25 void dfs1(node *way,int x,int y,int d,int step)
 26 {///左转优先
 27     way[step].row = x;
 28     way[step].col = y;
 29     way[step].dir = d;
 30     if(x==r3 && y==c3)///走到出口
 31     {
 32         step1 = step;
 33         flag1 = true;
 34         return;
 35     }
 36     for(int i=-1;i<=3;i++)
 37     {
 38         int tempDir = (way[step].dir + 4 + i)%4;///进行旋转
 39         int xx = way[step].row + dr[tempDir];
 40         int yy = way[step].col + dc[tempDir];
 41         if(inside(xx,yy) && square[xx][yy]!=\'#\')
 42         {///没有出界,可以行走
 43             dfs1(way,xx,yy,tempDir,step+1);
 44         }
 45         if(flag1)
 46             return;
 47     }
 48     return;
 49 }
 50 
 51 int step2;bool flag2;
 52 void dfs2(node *way,int x,int y,int d,int step)
 53 {///右转优先
 54     way[step].row = x;
 55     way[step].col = y;
 56     way[step].dir = d;
 57     if(x==r3 && y==c3)///走到出口
 58     {
 59         step2 = step;
 60         flag2 = true;
 61         return;
 62     }
 63     for(int i=1;i>=-2;i--)
 64     {
 65         int tempDir = (way[step].dir + 4 + i)%4;///进行旋转
 66         int xx = way[step].row + dr[tempDir];
 67         int yy = way[step].col + dc[tempDir];
 68         if(inside(xx,yy) && square[xx][yy]!=\'#\')
 69         {///没有出界,可以行走
 70             dfs2(way,xx,yy,tempDir,step+1);
 71         }
 72         if(flag2)
 73             return;
 74     }
 75     return;
 76 }
 77 node d[maxn][maxn][4];
 78 
 79 void bfs(int x,int y,int d)
 80 {
 81     queue<node> q;
 82     node u(x,y,d,1);///入口结点
 83     q.push(u);
 84     while(!q.empty())
 85     {
 86         node u = q.front();q.pop();
 87         if(u.row == r3 && u.col == c3)
 88         {
 89             cout<<u.deep<<endl;
 90             return;
 91         }
 92         for(int i=0;i<=3;i++)
 93         {
 94             int tempDir = (u.dir +i)%4;///进行旋转
 95             int xx = u.row + dr[tempDir];
 96             int yy = u.col + dc[tempDir];
 97             if(inside(xx,yy) && square[xx][yy]!=\'#\')
 98             {///没有出界,可以行走
 99                 node v(xx,yy,tempDir,u.deep+1);
100                 q.push(v);
101             }
102         }
103     }
104 }
105 
106 int startDir()
107 {///计算从入口进入之后的方向
108     if(r0 == 1) return 2;
109     else if(r0 == r) return 0;
110     else if(c0 == 1) return 1;
111     else return 3;
112 }
113 int main()
114 {
115     int n;
116     cin>>n;
117     while(n--)
118     {
119         cin>>c>>r;///输入为先输入列数,在输入行数
120         char temp;
121         for(int i=1;i<=r;i++)
122             for(int j=1;j<=c;j++)
123             {
124                 temp = getchar();
125                 while(temp == \'\\n\') temp = getchar();
126                 square[i][j] = temp;
127                 if(temp == \'S\'){r0 = i;c0 = j;}
128                 if(temp == \'E\'){r3 = i;c3 = j;}
129             }
130         node *way = new node[maxn*maxn];
131         ///求解左转优先
132         flag1 = false;step1 = 1;
133         int startdir = startDir();
134         dfs1(way,r0,c0,startdir,1);
135         if(flag1) cout<<step1<<" ";
136         ///求解右转优先
137         flag2 = false;step2 = 1;
138         dfs2(way,r0,c0,startdir,1);
139         if(flag2) cout<<step2<<" ";
140         ///求解最短路径
141         bfs(r0,c0,startdir);
142     }
143     return 0;
144 }

 

 最终成功代码

Time Limit Exceeded原因:POJ对STL兼容性不高,使用queue超时

其次,DFS使用尾递归形式,遇到可行解,直接向下一层搜索

最后,BFS不能走重复路线,否则会陷入死循环,Runtime Error

仅此告诫自己

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 using namespace std;
  5 int r,c;///行r,列c
  6 int r0,c0,r3,c3;///r0,c0用来标记入口,r3,c3用来标记出口
  7 
  8 const int maxn = 42;
  9 char square[maxn][maxn];
 10 const int dr[] = {-1,0,1,0};
 11 const int dc[] = { 0,1,0,-1};
 12 
 13 struct node{
 14 int row,col,deep;
 15 int dir;///0123对应NESW
 16 node(int row=0,int col=0,int dir=0,int deep=0):row(row),col(col),dir(dir),deep(deep){}
 17 };
 18 bool inside(int xx,int yy)
 19 {
 20     return xx>=1 && xx<=r && yy>=1 && yy<=c;
 21 }
 22 int dfs12(int x,int y,int d)
 23 {///左转优先
 24     if(square[x][y] == \'E\')
 25         return 1;
 26     int tempDir,xx,yy;
 27     for(int i=-1;i<=3;i++)
 28     {
 29         tempDir = (d + 4 + i)%4;///进行旋转
 30         xx = x + dr[tempDir];
 31         yy = y + dc[tempDir];
 32         if(inside(xx,yy) && square[xx][yy]!=\'#\')
 33         {///没有出界,可以行走
 34             break;
 35         }
 36     }
 37     return dfs12(xx,yy,tempDir)+1;
 38 }
 39 int dfs22(int x,int y,int d)
 40 {///you转优先
 41     if(square[x][y] == \'E\')
 42         return 1;
 43     int tempDir,xx,yy;
 44 
 45     for(int i=1;i>=-2;i--)
 46     {
 47         tempDir = (d + 4 + i)%4;///进行旋转
 48         xx = x + dr[tempDir];
 49         yy = y + dc[tempDir];
 50         if(inside(xx,yy) && square[xx][yy]!=\'#\')
 51         {///没有出界,可以行走
 52             break;
 53         }
 54     }
 55     return dfs22(xx,yy,tempDir)+1;
 56 }
 57 
 58 node queue[1600];
 59 bool has_walk[maxn][maxn];
 60 void bfs(int x,int y,int d)
 61 {
 62     int head=0,tail=1;
 63     node u(x,y,d,1);
 64     has_walk[x][y] = false;
 65     queue[head] = u;///入口结点
 66     while(head<tail)
 67     {
 68         node u = queue[head++];
 69         if(u.row == r3 && u.col == c3)
 70         {
 71             cout<<u.deep<<endl;
 72             return;
 73         }
 74         for(int i=0;i<=3;i++)
 75         {
 76             int tempDir = (u.dir +i)%4;///进行旋转
 77             int xx = u.row + dr[tempDir];
 78             int yy = u.col + dc[tempDir];
 79             if(inside(xx,yy) && square[xx][yy]!=\'#\' && has_walk[xx][yy])
 80             {///没有出界,可以行走,没有走过true
 81                 node v(xx,yy,tempDir,u.deep+1);
 82                 has_walk[xx][yy] = false;
 83                 queue[tail] = v;
 84                 tail++;
 85             }
 86         }
 87     }
 88 }
 89 
 90 int startDir()
 91 {///计算从入口进入之后的方向
 92     if(r0 == 1) return 2;
 93     else if(r0 == r) return 0;
 94     else if(c0 == 1) return 1;
 95     else return 3;
 96 }
 97 int main()
 98 {
 99     int n;
100     while(cin>>n)
101     while(n--)
102     {
103         cin>>c>>r;///输入为先输入列数,在输入行数
104         memset(has_walk,true,sizeof(has_walk));///true表示当前格子没有走过,可以走
105         char temp;
106         for(int i=1;i<=r;i++)
107             for(int j=1;j<=c;j++)
108             {
109                 temp = getchar();
110                 while(temp == \'\\n\') temp = getchar();
111                 square[i][j] = temp;
112                 if(temp == \'S\'){r0 = i;c0 = j;}
113                 if(temp == \'E\'){r3 = i;c3 = j;}
114             }
115         ///求解左转优先
116         int startdir = startDir();
117         cout<<dfs12(r0,c0,startdir)<<" ";
118         ///求解右转优先
119         cout<<dfs22(r0,c0,startdir)<<" ";
120         ///求解最短路径
121         bfs(r0,c0,startdir);
122     }
123     return 0;
124 }

 

最后给大家提供点测试样例:

5
8 8
########
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S#E####
9 5
#########
#.#.#.#.#
S.......E
#.#.#.#.#
#########
8 5
########
#.#.#..#
S......E
#.#.#..#
########
2 3
##
SE
##
8 8
######E#
#......#
#.####.#
#.####.#
#.####.#
#.####.#
#...#..#
#S######
结果:
37 5 5
17 17 9
14 14 8
2 2 2
13 29 13

 

以上是关于POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE的主要内容,如果未能解决你的问题,请参考以下文章

POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

poj3083

POJ2488&&3083&&3009&&1321&&2251&&2049

Out of Hay POJ - 2395

POJ 2151:Check the difficulty of problems 概率DP

The Children of Redux