[蓝桥杯2015决赛]穿越雷区
题目链接:http://oj.ecustacm.cn/problem.php?id=1266
想法:宽搜,判断上一步走的位置上的字符与下一个要走的位置的字符是否相同。如果相同,则跳过,不同则可以往下走
#include <iostream> #include <cstring> #include <vector> #include <queue> #include <algorithm> using namespace std; struct Node { int x,y; }; const int L = 109; char data[L][L]; // 数据 int path[L][L]; // 记录路径 Node dir[4]; // 方向 ,上下左右 int n; Node ap,bp; // 记录A,B位置 // 初始化方向变量和path数据 void init() { dir[0].x = -1; dir[0].y = 0; dir[1].x = 1; dir[1].y = 0; dir[2].x = 0; dir[2].y = -1; dir[3].x = 0; dir[3].y = 1; memset(path, 0, sizeof path); } // 宽搜 void bfs() { queue<Node> q; q.push(ap); int flag = 0; while(!q.empty() && flag == 0) { Node p = q.front(); q.pop(); int cx, cy; for (int i = 0; i < 4; i++) { cx = p.x + dir[i].x; cy = p.y + dir[i].y; // 找到 if (cx == bp.x && cy == bp.y) flag = 1; // 位置范围超出 if (cx < 0 || cx >= n || cy < 0 || cy >= n) continue; // 如果不是交替的字符 if (data[cx][cy] == data[p.x][p.y]) continue;、 // 如果之前该位置已经走过,再判断当前路径是否比之前走的路径更短,大于则跳过 if (path[p.x][p.y] + 1 > path[cx][cy] && path[cx][cy] != 0) continue; // 1.当前位置没有走过 // 2.如果更短则替换 path[cx][cy] = path[p.x][p.y] + 1; // 在之前的位置路径长度加1 Node n; n.x = cx; n.y = cy; q.push(n); // 加入队列 } } } int main() { init(); scanf("%d", &n); string d; getline(cin, d); // 排除第一行的回车符 // 输入数据 for (int i = 0; i < n; i++) { getline(cin, d); int k = 0; for (int j = 0; j < d.size(); j++) { if (d[j] != ' ') { if (d[j] == 'A') ap.x = i,ap.y = k; if (d[j] == 'B') bp.x = i,bp.y = k; data[i][k++] = d[j]; } } } bfs(); cout << path[bp.x][bp.y] << endl; return 0; }
。。。。。。。。。。。