1412: XY之说走就走的旅行
时间限制: 1 Sec 内存限制: 128 MB提交: 903 解决: 128
[提交][状态][讨论版]
题目描述
X和Y是好基友,他们决定进行一次说走就走的旅行,因此俩人约好在车站会合。
城市中有多个车站,为了节省时间,他们约好的车站应该离双方的家都比较近。
即若X与车站i距离为dXi,Y与车站i距离为dYi,则该车站为max(dXi,dYi)最小的车站。(只有‘#’的位置无法通过)
输入
多组数据,请处理到文件尾。
对于每组数据:
第一行含有两个正整数n,m
接下来是一个n行m列的矩阵,表示城市地图,矩阵中任意元素只和上下左右元素(如果存在且可达)相邻,相邻元素之间距离为1。
其中” . ”代表可走的街道,” # ”代表不可走的街道,” P ”表示车站,” X ”代表X的家,” Y ”代表Y的家。
输出
对于每组数据输出一行,含有两个整数x,y,以空格分隔,代表约定好的车站所在的行号和列号(1<=x<=n,1<=y<=m)。
若存在多个满足条件的解,则答案应为行号最小的;若还存在多个解,则答案应应为列号最小的。
保证解一定存在。
样例输入
3 3 X.P P#. ..Y 2 2 XP PY
样例输出
1 3 1 2
提示
1<=n,m<=200
这是一道水题,却为什么debug那么久呢....
考虑不全面, 只用一个二维数组初始化为0, 然后分别以X,Y为起点bfs. 更新d[i][j]=max(d[i][j], len);
len表示bfs时距离起点的距离. 这里有漏洞啊
可能有点P点到不了, 最后其值为0. 反而是最小的了
可能P点可以到X,但不可以到Y. 题目要求两点都可以到达(其实不存在这样的点)
还有 一定要记得初始化!!!(那么不细心,怎么追的上你啊)
#include <bits/stdc++.h> using namespace std; const int N = 207; const int inf = 0x3f3f3f3f; char mp[N][N]; bool vis[N][N]; int d[N][N]; int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; int n, m; struct node { int x, y; int val; }; bool isok(int x, int y) { return (x >= 1 && x <= n && y >= 1 && y <= m); } void bfs(int x, int y) { memset(vis, 0, sizeof(vis)); queue <node> q; node tmp = {x, y, 0}; vis[x][y] = 1; q.push(tmp); while (!q.empty()) { tmp = q.front(); q.pop(); int sx = tmp.x, sy = tmp.y; d[sx][sy] = max (d[sx][sy], tmp.val); for (int i = 0; i < 4; i++) { int tx = sx + dx[i]; int ty = sy + dy[i]; if (isok(tx, ty) && mp[tx][ty] != '#' && !vis[tx][ty]) { vis[tx][ty] = 1; node tm = {tx, ty, tmp.val + 1}; q.push(tm); } } } } int main () { int x1, y1, x2, y2; while (~scanf("%d %d", &n, &m)) { for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) { scanf(" %c", &mp[i][j]); if (mp[i][j] == 'X') { x1 = i; y1 = j; } if (mp[i][j] == 'Y') { x2 = i; y2 = j; } } memset(d, 0, sizeof(d)); // 记得要初始化 bfs(x1, y1); bfs(x2, y2); int ans = inf, x, y; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) if (mp[i][j] == 'P' && d[i][j] && d[i][j] < ans) { ans = d[i][j]; x = i; y = j; } printf("%d %d\n", x, y); } return 0; }
抓住青春的尾巴。。。