1.http://acm.hdu.edu.cn/showproblem.php?pid=1312
题意:在一个仅有红黑格子组成的矩形中,一个人只能走上下左右相邻黑色格子,问从起点开始共能走多少个格子?
’#‘:红色格子
’.‘: 黑色格子;
’@‘:起点
BFS 和 DFS 都可以遍历所有走的点,每次走过一点时,计数++即可;
2.http://acm.hdu.edu.cn/showproblem.php?pid=1728
由题可知,在限制转弯数量的前提下 能够从一点走到另一个点即可;BFS 和 DFS都能求出解。我 DFS 还没实现
需要注意:1.点坐标是从 1 开始的。
2.最短的路径可能不满足转弯数的限制。
3.起点与终点重合。
超内存代码:还没找到原因。
1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 using namespace std; 5 #define N 105 6 7 struct Pos 8 { 9 int x, y; 10 int turn; 11 int dire; 12 }S, E; 13 char map[N][N]; 14 bool used[N][N][12][4]; 15 int dir[][2]={1,0, -1,0, 0,1, 0,-1}; 16 int n, m, k; 17 18 bool Judge (Pos s) 19 { 20 if (s.x>=1 && s.x<=m && s.y>=1 && s.y<=n && map[s.x][s.y]==‘.‘ && !used[s.x][s.y][S.turn][S.dire] && s.turn <= k) 21 return true; 22 return false; 23 } 24 25 bool bfs () 26 { 27 Pos Pre, Cur; 28 queue <Pos> Q; 29 while (!Q.empty ()) Q.pop(); 30 memset (used, 0, sizeof used); 31 32 S.dire = -1; 33 S.turn = 0; 34 used[S.x][S.y][S.turn][S.dire] = true; 35 Q.push (S); 36 while (!Q.empty ()) 37 { 38 Pre = Q.front (); 39 Cur = Pre; 40 Q.pop(); 41 if (Cur.x==E.x && Cur.y==E.y) 42 return true; 43 for(int i=0; i<4; i++) 44 { 45 Cur.x = Pre.x + dir[i][0]; 46 Cur.y = Pre.y + dir[i][1]; 47 Cur.turn = Pre.turn; 48 Cur.dire = i; 49 if (Cur.dire != Pre.dire && Pre.dire !=-1) 50 Cur.turn++; 51 if (Judge (Cur)) 52 { 53 used[Cur.x][Cur.y][Cur.turn][Cur.dire] = true; 54 Q.push (Cur); 55 } 56 } 57 } 58 return false; 59 } 60 61 int main () 62 { 63 int t; 64 // freopen ("test.txt","r",stdin); 65 scanf ("%d",&t); 66 while (t--) 67 { 68 scanf ("%d%d",&m, &n); 69 for (int i=1; i<=m; i++) 70 for (int j=1; j<=n; j++) 71 scanf (" %c", map[i]+j); 72 scanf ("%d%d%d%d%d",&k, &S.y, &S.x, &E.y, &E.x); 73 74 puts ((bfs ()?"yes":"no")); 75 } 76 return 0; 77 }
1.http://acm.hdu.edu.cn/showproblem.php?pid=1010;
题意:在一个矩形的迷宫里面, 问是否可以恰好在 给定的时间点 走到出口。
‘X‘:墙壁;
’S‘:起点;
‘D‘:出口;
’.‘: 空地。
这道题,是问你是否有解,不是要求最优解,所以可以用DFS深度搜索, 奇偶性剪枝+路径剪枝优化时间防TLE。如果硬是要用BFS按理来说应该是可以求出结果的,不过我BFS一直WA,一直想不通。留着以后进步了再斟酌。
DFS代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 using namespace std; 5 6 int n, m, t, ex, ey; 7 char map[10][10]; 8 bool visit[10][10], flag; 9 int dir[][2]={1,0, -1,0, 0,1, 0,-1}; 10 11 void dfs (int x, int y, int cnt) 12 { 13 if (x<0 || x>n-1 || y<0 || y>m-1) return; 14 if (flag || cnt > t) return; 15 if (x==ex && y==ey) 16 { 17 if (cnt == t) 18 flag = true; 19 return; 20 } 21 for (int i=0; i<4; i++) 22 { 23 int xx = x + dir[i][0]; 24 int yy = y + dir[i][1]; 25 if (map[xx][yy]==‘X‘ || visit[xx][yy]) continue; 26 visit[xx][yy] = true; 27 dfs (xx, yy, cnt+1); 28 if (flag) return; 29 visit[xx][yy] = false; 30 } 31 } 32 int main () 33 { 34 // freopen ("test.txt","r",stdin); 35 while (~scanf ("%d%d%d",&n, &m, &t) && n+m+t) 36 { 37 int wall=0, sx, sy; 38 for (int i=0; i<n; i++) 39 for (int j=0; j<m; j++) 40 { 41 scanf (" %c",map[i]+j); 42 if (map[i][j] == ‘S‘) 43 { 44 sx = i; sy = j; 45 } 46 else if (map[i][j]==‘D‘) 47 { 48 ex = i; ey = j; 49 } 50 else if (map[i][j]==‘X‘) 51 wall++; 52 } 53 //路径剪枝 54 if (n*m-wall < t) 55 { 56 puts ("NO"); 57 continue; 58 } 59 //奇偶性剪枝 60 int tmp = fabs (sx-ex) + fabs (sy-ey); 61 if ((t - tmp) & 1) 62 { 63 puts ("NO"); 64 continue; 65 } 66 memset (visit, 0, sizeof visit); 67 flag = false; 68 visit[sx][sy] = true; 69 dfs(sx, sy, 0); 70 puts ((flag?"YES":"NO")); 71 } 72 return 0; 73 }
时间: 2024-10-29 19:13:00