都比较简单,直接贴代码吧。
poj1979 DFS
题目大意:给你一个二维数组,.表示可以到达,#表示障碍,@表示起始位置,问你能到达的最大地点有多少个,每次只能走上下左右
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int n, m, sx, sy, ans; int pd[30][30]; char maze[30][30]; int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}; void dfs(int x, int y) { ans++, pd[x][y] = 1; for(int i = 0; i < 4; i++) { int nx = x + dx[i], ny = y + dy[i]; if(nx < 0 || nx >= n || ny < 0 || ny >= m) continue; if(pd[nx][ny] == 1 || maze[nx][ny] != ‘.‘) continue; dfs(nx, ny); } } int main() { while(scanf("%d%d", &n, &m) != EOF) { if(n == 0 && m == 0) break; int t = n; n = m, m = t; for(int i = 0; i < n; i++) scanf("%s",maze[i]); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) if(maze[i][j] == ‘@‘) sx = i, sy = j; ans = 0; memset(pd, 0, sizeof(pd)); dfs(sx, sy); printf("%d\n", ans); } return 0; }
poj3009 DFS
题目大意:
就是要求把一个冰壶从起点“2”用最少的步数移动到终点“3”
其中0为移动区域,1为石头区域,冰壶一旦想着某个方向运动就不会停止,也不会改变方向(想想冰壶在冰上滑动),除非冰壶撞到石头1 或者 到达终点 3
要注意:可能会出边界,边界是没有障碍物抵挡的!
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int n, m, sx, sy, tx, ty, ans; int maze[30][30]; int dx[4] = {0, 1, 0, -1}, dy[4] = {1, 0, -1, 0}; int dfs(int k, int x, int y) { if(x == tx && y == ty) return k - 1; if(k > 10) return -1; int nx, ny, min = -1, res; for(int i = 0; i < 4; i++) { nx = x + dx[i], ny = y + dy[i]; if(nx < 0 || ny < 0 || nx > n-1 || ny > m-1 || maze[nx][ny] == 1) continue; while(1) { if(nx == tx && ny == ty) return k; nx += dx[i], ny += dy[i]; if(nx < 0 || ny < 0 || nx > n-1 || ny > m-1) break; if(nx == tx && ny == ty) return k; if(maze[nx][ny] == 1) { maze[nx][ny] = 0; res = dfs(k + 1, nx - dx[i], ny - dy[i]); maze[nx][ny] = 1; if(min == -1) min = res; else if(res != -1 && res < min) min = res; break; } } } return min; } int main() { while(scanf("%d%d", &m, &n) != EOF) { memset(maze, 0, sizeof(maze)); if(n == 0 && m == 0) break; for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) { scanf("%d", &maze[i][j]); if(maze[i][j] == 2) sx = i, sy = j, maze[i][j] = 0; if(maze[i][j] == 3) tx = i, ty = j, maze[i][j] = 0; } ans = dfs(1, sx, sy); printf("%d\n", ans); } return 0; }
poj3669 BFS
题目大意:
给定几个坐标,在这些坐标上 t 时刻会有陨石雨。
怎样在最短的时间内找到一个安全的地方。
方法:预处理,把每个坐标有陨石的地方预处理出来,这样在bfs的时候会很简单,比如不用考虑待在原点不懂,或者往回走之类的
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; int dt[400][400]; int dx[5] = {0, 0, 1, 0, -1}, dy[5] = {0, 1, 0, -1, 0}; struct node { int x, y, t; }; int bfs() { if(dt[0][0] == 0) return -1; if(dt[0][0] == -1 ) return 0; queue<node> q; node temp,newt; temp.x = 0, temp.y = 0, temp.t = 0; q.push(temp); while(!q.empty()) { temp = q.front(); q.pop(); for(int i = 1; i < 5; i++) { newt.x = temp.x + dx[i]; newt.y = temp.y + dy[i]; newt.t = temp.t + 1; if(newt.x < 0 || newt.y < 0) continue; if(dt[newt.x][newt.y] == -1) return newt.t; if(dt[newt.x][newt.y] <= newt.t) continue; q.push(newt); dt[newt.x][newt.y] = newt.t; } } return -1; } int main() { int m; while(scanf("%d", &m) != EOF) { int x, y, t; memset(dt, -1, sizeof(dt)); for(int j = 0; j < m; j++) { scanf("%d%d%d", &x, &y, &t); for(int i = 0; i < 5; i++) { int nx = x + dx[i], ny = y + dy[i]; if(nx < 0 || ny < 0) continue; if(dt[nx][ny] == -1) dt[nx][ny] = t; else if(dt[nx][ny] > t) dt[nx][ny] = t; } } printf("%d\n",bfs()); } return 0; }
时间: 2024-11-06 19:41:31