1. 程式人生 > >POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

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

cin 列數 tle 圖片 逆時針 sta div ima ostream

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 }

技術分享圖片

技術分享圖片

尾遞歸形式+精簡代碼(依舊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 
  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 
 14 struct node{
 15 int row,col,deep;
 16 int dir;///0123對應NESW
 17 node(int row=0,int col=0,int dir=0,int deep=0):row(row),col(col),dir(dir),deep(deep){}
 18 };
 19 
 20 int dfs12(int x,int y,int d)
 21 {///左轉優先
 22 
 23     if(square[x][y] == E)
 24         return 1;
 25     int tempDir,xx,yy;
 26     for(int i=-1;i<=3;i++)
 27     {
 28         tempDir = (d + 4 + i)%4;///進行旋轉
 29         xx = x + dr[tempDir];
 30         yy = y + dc[tempDir];
 31         if(square[xx][yy]==. || square[xx][yy]==E ||square[xx][yy]==S)
 32         {///沒有出界,可以行走
 33             break;
 34         }
 35     }
 36     return dfs12(xx,yy,tempDir)+1;
 37 }
 38 int dfs22(int x,int y,int d)
 39 {///you轉優先
 40     if(square[x][y] == E)
 41         return 1;
 42     int tempDir,xx,yy;
 43 
 44     for(int i=1;i>=-2;i--)
 45     {
 46         tempDir = (d + 4 + i)%4;///進行旋轉
 47         xx = x + dr[tempDir];
 48         yy = y + dc[tempDir];
 49         if(square[xx][yy]==. || square[xx][yy]==E ||square[xx][yy]==S)
 50         {///沒有出界,可以行走
 51             break;
 52         }
 53     }
 54     return dfs22(xx,yy,tempDir)+1;
 55 }
 56 
 57 node d[maxn][maxn][4];
 58 
 59 void bfs(int x,int y,int d)
 60 {
 61     queue<node> q;
 62     node u(x,y,d,1);///入口結點
 63     q.push(u);
 64     while(!q.empty())
 65     {
 66         node u = q.front();q.pop();
 67         if(u.row == r3 && u.col == c3)
 68         {
 69             cout<<u.deep<<endl;
 70             return;
 71         }
 72         for(int i=0;i<=3;i++)
 73         {
 74             int tempDir = (u.dir +i)%4;///進行旋轉
 75             int xx = u.row + dr[tempDir];
 76             int yy = u.col + dc[tempDir];
 77             if(square[xx][yy]==. || square[xx][yy]==E ||square[xx][yy]==S)
 78             {///沒有出界,可以行走
 79                 node v(xx,yy,tempDir,u.deep+1);
 80                 q.push(v);
 81             }
 82         }
 83     }
 84 }
 85 
 86 int startDir()
 87 {///計算從入口進入之後的方向
 88     if(r0 == 1) return 2;
 89     else if(r0 == r) return 0;
 90     else if(c0 == 1) return 1;
 91     else return 3;
 92 }
 93 int main()
 94 {
 95     int n;
 96     cin>>n;
 97     while(n--)
 98     {
 99         cin>>c>>r;///輸入為先輸入列數,在輸入行數
100         char temp;
101         for(int i=1;i<=r;i++)
102             for(int j=1;j<=c;j++)
103             {
104                 temp = getchar();
105                 while(temp == \n) temp = getchar();
106                 square[i][j] = temp;
107                 if(temp == S){r0 = i;c0 = j;}
108                 if(temp == E){r3 = i;c3 = j;}
109             }
110         ///求解左轉優先
111         int startdir = startDir();
112         cout<<dfs12(r0,c0,startdir)<<" ";
113         ///求解右轉優先
114         cout<<dfs22(r0,c0,startdir)<<" ";
115         ///求解最短路徑
116         bfs(r0,c0,startdir);
117     }
118     return 0;
119 }

技術分享圖片

暫存問題……

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