P1300 题解

P1300 城市街道交通费系统

题目大意

给定一张图,改变方向需要一定的花费,试找出一条路径使得花费最小,输出这个最小花费。

思路

首先注意到数据范围:对于 $100\%$ 的数据:$4 \leq h,w \leq 30$。可以考虑直接搜索求解。

首先需要预处理整张地图,可以令北、西、南、东分别为 $0$、$1$、$2$、$3$。设当前方向为 $z$,则易知左转、右转、掉头操作之后的方向分别为 $(z + 1) \bmod 4$,$(z + 3) \bmod 4$,$(z + 2) \bmod 4$,接下来就可以搜索了。搜索的同时可以顺便剪枝以降低时间复杂度,具体细节请看代码……

代码

#include <iostream>
#include <cstring>
#define MAXN 35
using namespace std;
int n, m, dx, dy, dz, ans = 998244353;
int d[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}}; // 移动坐标
int a[MAXN][MAXN], dis[MAXN][MAXN][4], tot;
char s[MAXN];
void dfs(int x, int y, int z, int c){
    if(dis[x][y][z] <= c || c >= ans)return; // 特判
    dis[x][y][z] = c;bool tmp = 0;
    if(a[x][y] == 2)ans = min(ans, c); // 更新答案
    if(a[x + d[z][0]][y + d[z][1]])tmp = 1, dfs(x + d[z][0], y + d[z][1], z, c); // 前进
    if(a[x + d[(z + 1) % 4][0]][y + d[(z + 1) % 4][1]]){tmp = 1;dfs(x + d[(z + 1) % 4][0], y + d[(z + 1) % 4][1], (z + 1) % 4, c + 1);} // 左转
    if(a[x + d[(z + 3) % 4][0]][y + d[(z + 3) % 4][1]]){tmp = 1;dfs(x + d[(z + 3) % 4][0], y + d[(z + 3) % 4][1], (z + 3) % 4, c + 5);} // 右转
    if(a[x + d[(z + 2) % 4][0]][y + d[(z + 2) % 4][1]]&&!tmp)dfs(x + d[(z + 2) % 4][0], y + d[(z + 2) % 4][1], (z + 2) % 4, c + 10); // 掉头
}
int main(){
    cin >> n >> m;
    for(int i = 1 ; i <= n ; i ++){
        cin >> s + 1;
        for(int j = 1 ; j <= m ; j ++){
            a[i][j] = 1;
            switch(s[j]){ // 预处理地图
                case '.':{a[i][j] = 0;break;}
                case '#':{break;}
                case 'F':{a[i][j] = 2;break;}
                case 'N':{dx = i;dy = j;dz = 0;break;}
                case 'W':{dx = i;dy = j;dz = 1;break;}
                case 'S':{dx = i;dy = j;dz = 2;break;}
                case 'E':{dx = i;dy = j;dz = 3;break;}
            }
        }
    }
    memset(dis, 114514, sizeof dis);
    dfs(dx, dy, dz, 0); // 搜索
    cout << ans << endl; // 输出最小花费
    return 0;
} // 完结撒花~~
posted @ 2023-08-23 11:00  tsqtsqtsq  阅读(17)  评论(0)    收藏  举报  来源