社区讨论
58分BFS求救,有详细注释
P1825[USACO11OPEN] Corn Maze S参与者 1已保存回复 0
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @lo2yw68h
- 此快照首次捕获于
- 2023/10/23 22:02 2 年前
- 此快照最后确认于
- 2023/10/23 22:02 2 年前
CPP
#include <iostream>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 505 , M = 26;
typedef pair<int,int> pll;
int n , m , a[M] , ans[N][N];
char s[N][N];
pll point1[M] , point2[M] , S , T;
bool st[N][N];
bool check(int x,int y){
if(x < 1 || x > n || y < 1 || y > m) return false;
if(s[x][y] == '#' || st[x][y]) return false;
return true;
}
void bfs(int i, int j)
{
int dx[] = {1 , -1 , 0 , 0};
int dy[] = {0 , 0 , 1 , -1};
queue<pll> q;
q.push({i , j});
st[i][j] = true;
while(q.size())
{
auto t = q.front();
q.pop();
//到达终点
if(s[t.first][t.second] == '=')
{
cout << ans[t.first][t.second];
return ;
}
if(s[t.first][t.second] >= 'A' && s[t.first][t.second] <= 'Z'){
//取出到这个点的时间
int k = ans[t.first][t.second];
//取出俩个传送门的地址
auto t1 = point1[s[t.first][t.second] - 'A'];
auto t2 = point2[s[t.first][t.second] - 'A'];
//判断当前在哪个传送门
if(t == t1) t = t2;
else t = t1;
st[t.first][t.second] = true;
//传送过去后耗时应该相同
ans[t.first][t.second] = k;
}
//遍历上下左右四个方向
for (int i = 0 ; i <= 3 ; ++i)
{
int rx = t.first + dx[i] , ry = t.second + dy[i];
//如果坐标合法
if(check(rx,ry)){
//入队
q.push({rx , ry});
//记为已到达
st[rx][ry] = true;
//
ans[rx][ry] = ans[t.first][t.second] + 1;
}
}
}
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin >> n >> m;
for (int i = 1 ; i <= n ; ++i)
{
for (int j = 1 ; j <= m ; ++j){
cin >> s[i][j];
if(s[i][j] == '=')
{
T = {i , j};
}
if(s[i][j] == '@')
{
S = {i , j};
}
//记录传送点
if(s[i][j] >= 'A' && s[i][j] <= 'Z')
{
int t = s[i][j] - 'A';
if(a[t] == 0) {
a[t] = 1;
point1[t] = {i , j};
}
else{
point2[t] = {i , j};
}
}
}
}
bfs(S.first , S.second);
return 0;
}
回复
共 0 条回复,欢迎继续交流。
正在加载回复...