洛谷__P1300 城市街道交通费系统(搜索)
题目链接:P1300 城市街道交通费系统 - 洛谷
题目大意:
在一个网格地图中,汽车从起点(给定初始朝向)到终点,在道路 # 上行驶。
直走免费,左转费 1,右转费 5,仅当无法直行、左转、右转时才允许调头(费 10)
.表示障碍区。#表示道路。E表示起始点且汽车面朝东。W表示起始点且汽车面朝西。N表示起始点且汽车面朝北。S表示起始点且汽车面朝南。F表示终点。
求:从起点到终点的最小花费
思路:
只需在普通的搜索的基础上加个方向即可,
根据方向对转弯进行操作
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;
const int N = 36, mod = 998244353;
int n, m, res = inf;
char e[N][N];
// n w s e
int dx[4] = {-1, 0, 1, 0 };
int dy[4] = {0, -1, 0, 1};
int sx, sy, sw;//x,y,方向
int dis[N][N][4];
void dfs(int x, int y, int w, int val) {
if (dis[x][y][w] <= val || val >= res) return;//剪枝
dis[x][y][w] = val;
if (e[x][y] == 'F') res = min(res, dis[x][y][w]);//终点
bool ok = false;
int nx = x + dx[w], ny = y + dy[w];//直走
int lw = (w + 1) % 4, lx = x + dx[lw], ly = y + dy[lw];//左转
int rw = (w + 3) % 4, rx = x + dx[rw], ry = y + dy[rw];//右转
int bw = (w + 2) % 4, bx = x + dx[bw], by = y + dy[bw];//后转
if (e[nx][ny] != '.') ok = true, dfs(nx, ny, w, val);
if (e[lx][ly] != '.') ok = true, dfs(lx, ly, lw, val + 1);
if (e[rx][ry] != '.') ok = true, dfs(rx, ry, rw, val + 5);
if (e[bx][by] != '.' && !ok) dfs(bx, by, bw, val + 10);
}
void solve() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
cin >> e[i][j];
if (e[i][j] == 'N') sx = i, sy = j, sw = 0;
if (e[i][j] == 'W') sx = i, sy = j, sw = 1;
if (e[i][j] == 'S') sx = i, sy = j, sw = 2;
if (e[i][j] == 'E') sx = i, sy = j, sw = 3;
}
}
mst(dis, 1);
dfs(sx, sy, sw, 0);
cout << res << endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号