作业介绍
/*
男(三步)女(一步)鬼(上下左右四个方向两个单位)
鬼会到达两步之内能到达的地方,变为自己的领地
双向宽搜索,按照秒来搜索,注意可以原地不动
每一秒宽搜,男孩三步以内能到的位置标记出来
女孩一步以内能到的位置标记出来,
如果存在同一秒的是,两个会在同一个位置且当前位置没有鬼
判断这个位置是否有鬼,可以判断这个位置和鬼的曼哈顿距离是否超过2K
时间复杂度 O(n),每个各自只会被遍历一次
*/
#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int > PII;
const int N = 810;
int n, m;
char g[N][N];
int st[N][N];
PII ghost[2], boy, girl;
bool check(int x, int y, int step) {
if (x < 0 || x >= n || y < 0 || y >= m || g[x][y] == 'X' ) return 0;
for (int i = 0; i < 2; i++) {
if (abs(x - ghost[i].first) + abs(y - ghost[i].second) <= step * 2)
return 0;
}
return 1;
}
int bfs() {
int dx[] = {-1, 0, 1, 0}, dy[] = {0, 1, 0, -1};
int cnt = 0;
memset(st, 0, sizeof st);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
if (g[i][j] == 'M') boy = {i, j};
else if (g[i][j] == 'G') girl = {i, j};
else if (g[i][j] == 'Z') ghost[cnt++] = {i, j};
int step = 0;
queue<PII> qb, qg;
qb.push(boy), qg.push(girl);
// 双向 BFS
while (qb.size() || qg.size()) {
step++;
// 男生一次能走三秒
for (int i = 0; i < 3; i++) {
for (int j = 0, len = qb.size(); j < len ; j++) {
auto t = qb.front();
qb.pop();
int x = t.first, y = t.second;
if (!check(x, y, step)) continue;
for (int k = 0; k < 4 ; k++) {
int a = x + dx[k], b = y + dy[k];
if (check(a, b, step)) {
if (st[a][b] == 2) return step;
if (!st[a][b]) {
st[a][b] = 1;
qb.push({a, b});
}
}
}
}
}
// 女生一次只能走一秒
for (int i = 0; i < 1; i++) {
for (int j = 0, len = qg.size(); j < len ; j++) {
auto t = qg.front();
qg.pop();
int x = t.first, y = t.second;
if (!check(x, y, step)) continue;
for (int k = 0; k < 4 ; k++) {
int a = x + dx[k], b = y + dy[k];
if (check(a, b, step)) {
if (st[a][b] == 1) return step;
if (!st[a][b]) {
st[a][b] = 2;
qg.push({a, b});
}
}
}
}
}
}
return -1;
}
int main() {
int T;
cin >> T;
while (T--) {
cin >> n >> m;
for (int i = 0; i < n; i++)
cin >> g[i];
printf("%d\n", bfs());
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e4 + 5;
int n, m, cnt, ans = INT_MAX;
int men[N][4], book[55][55];
char mp[N][N];
bool flag;
struct node {
int x, y, t;
};
int dx[] = {0, 0, 0, 1, -1};
int dy[] = {0, 1, -1, 0, 0};
void bfs() {
queue<node>q;
q.push({1, 1, 1}), book[1][1] = 1;
while (!q.empty()) {
int nx = q.front().x;
int ny = q.front().y;
int nt = q.front().t;
q.pop();
if (nx == n and ny == m) {
cout << nt;
flag = 1;
return;
}
if (mp[nx][ny] == '$') {
for (int i = 1; i <= cnt; i++) {
if (book[men[i][1]][men[i][2]])
continue;
book[men[i][1]][men[i][2]] = 1;
q.push({men[i][1], men[i][2], nt});
}
}
for (int i = 1; i <= 4; i++) {
int vx = nx + dx[i];
int vy = ny + dy[i];
int time = nt + 1;
if (book[vx][vy] or mp[vx][vy] == '#' or vx < 1 or vy < 1 or vx > n or vy > m)
continue;
q.push({vx, vy, time}), book[vx][vy] = 1;
}
}
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> mp[i][j];
if (mp[i][j] == '$') {
men[++cnt][1] = i;
men[cnt][2] = j;
}
}
bfs();
if (!flag)
cout << -1;
return 0;
}
//by.pcx
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
int n, m, vis[N][N][10], flg, sx, sy;
char a[N][N];
int d[4][2] = {0, 1, 0, -1, -1, 0, 1, 0};
struct node {
int x, y, t, s;
bool operator < (const node a) const {
return t > a.t;
}
};
void bfs() {
priority_queue<node>q;
vis[sx][sy][6] = 1;
q.push({sx, sy, 0, 6});
while (!q.empty()) {
node u = q.top();
q.pop();
if (u.s <= 0)
continue;//只是跳过,不能直接return
if (a[u.x][u.y] == '3' && u.s > 0) {
cout << u.t;
flg = 1;
return;
}
for (int i = 0; i < 4; i++) {
int nx = u.x + d[i][0], ny = u.y + d[i][1];
if (nx < 1 || nx > n || ny < 1 || ny > m || a[nx][ny] == '0')
continue;
int now = u.s - 1;
if (now <= 0)//要先判断这个,不能先补血
continue;
if (a[nx][ny] == '4')
now = 6;
if (vis[nx][ny][now])
continue;
vis[nx][ny][now] = 1;
q.push({nx, ny, u.t + 1, now});
}
}
return;
}
int main() {
ios::sync_with_stdio(0), cin.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
if (a[i][j] == '2')
sx = i, sy = j;
}
}
bfs();
if (!flg)
cout << "-1";
return 0;
}
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 10;
int a[N][N], n, m;
int sx, sy, fx, fy;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
struct node {
int x, y, hp, t;
};
int res = 1e9;
int vis[N][N][7];
void bfs() {
queue<node> q;
q.push({sx, sy, 6, 0});
memset(vis, 0x3f, sizeof(vis));
vis[sx][sy][6] = 0;
while (!q.empty()) {
node t = q.front();
q.pop();
if (t.x == fx && t.y == fy) {
res = min(res, t.t );
}
for (int i = 0; i < 4; i++) {
int nx = t.x + dx[i];
int ny = t.y + dy[i];
int hp, cost;
if (nx < 1 || nx > n || ny < 1 || ny > m)
continue;
if (a[nx][ny] == 0)
continue;
if (t.hp == 1)
continue;
if (a[nx][ny] == 4)
hp = 6;
else
hp = t.hp - 1;
cost = t.t + 1;
if (cost < vis[nx][ny][hp]) {
q.push({nx, ny, hp, cost});
vis[nx][ny][hp] = cost;
}
}
}
}
signed main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
if (a[i][j] == 2)
sx = i, sy = j;
if (a[i][j] == 3)
fx = i, fy = j;
}
bfs();
if (res == 1e9)
cout << -1 << endl;
else
cout << res << endl;
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 110;
char a[N][N];
int n, m, sx, sy, fx, fy;
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
bool vis[N][N], flg = 1;
struct node {
int x, y, t;
// 自定义排序规则
bool operator < (const node a)const {
return t > a.t;
}
};
void bfs(int x, int y) {
vis[x][y] = 1;
priority_queue<node> q;
q.push({x, y, 0});
while (q.size()) {
auto t = q.top();
q.pop();
if (t.x == fx && t.y == fy) {
cout << t.t;
flg = 0;
return ;
}
// 拓展周围的点
for (int i = 0; i < 4; i++) {
int nx = t.x + dx[i];
int ny = t.y + dy[i];
if (nx < 1 || nx > n || ny < 1 || ny > m)
continue;
if (a[nx][ny] == '#')
continue;
if (vis[nx][ny])
continue;
vis[nx][ny] = 1;
if (a[nx][ny] <= '9' && a[nx][ny] >= '1')
q.push({nx, ny, t.t + 1 + a[nx][ny] - '0'});
else
q.push({nx, ny, t.t + 1});
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++) {
cin >> a[i][j];
if (a[i][j] == 'Z')
sx = i, sy = j;
if (a[i][j] == 'W')
fx = i, fy = j;
}
bfs(sx, sy);
if (flg)
puts("IMPOSSIBLE");
return 0;
}
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
struct node {
int x, y, t;
};
int n, m;
char a[N][N];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
bool vis[N][N];
void bfs(int x, int y) {
vis[x][y] = 1;
queue<node> q;
q.push({x, y, 1});
while (q.size()) {
auto t = q.front();
q.pop();
if (t.x == n && t.y == m) {
cout << t.t;
return ;
}
for (int i = 0; i < 4; i++) {
int nx = t.x + dx[i];
int ny = t.y + dy[i];
if (nx < 1 || nx > n || ny < 1 || ny > m)
continue;
if (a[nx][ny] == '#')
continue;
if (vis[nx][ny])
continue;
vis[nx][ny] = 1;
q.push({nx, ny, t.t + 1});
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
bfs(1, 1);
return 0;
}
//queue STL 中的队列
//queue<int> q; // 定义队列
//q.push(x); // 入队
//q.front(); // 队伍头
//q.pop(); // 出队
//q.size(); // q 的长度
//
//等价于 struct node {
// int first, second;
//}
//pair<int, int> p; // 默认的排序规则
//// 先按照 first 从小到大排序,再按照 second 从小到大排序
#include <bits/stdc++.h>
using namespace std;
const int N = 50;
char a[N][N];
int n, m;
bool flg = 1;
bool vis[N][N];
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
void bfs(int x, int y) {
queue<pair<int, int> >q;
vis[x][y] = 1;
q.push({x, y});
// 从队列头部开始拓展
while (q.size()) { // 当队列不为空
auto t = q.front();
q.pop(); // 队列的头
if (t.first == n && t.second == m) { // 找到了最终的结果
cout << "YES";
flg = 0;
return ;
}
// 没有找到,从当前点进行拓展
for (int i = 0; i < 4; i++) {
int nx = t.first + dx[i];
int ny = t.second + dy[i];
// 越界判断
if (nx < 1 || nx > n || ny < 1 || ny > m)
continue;
// 能否通过
if (a[nx][ny] == '#')
continue;
// 是否走过
if (vis[nx][ny])
continue;
vis[nx][ny] = 1;
q.push({nx, ny});
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
cin >> a[i][j];
bfs(1, 1);
if (flg)
cout << "NO";
return 0;
}
题目
认领作业后才可以查看作业内容。
- 状态
- 正在进行…
- 题目
- 19
- 开始时间
- 2026-7-1 0:00
- 截止时间
- 2026-8-31 23:59
- 可延期
- 24 小时