zoukankan      html  css  js  c++  java
  • Gym

    题意:

    给出一张地图和机器人还有出口的位置,地图上面有障碍。然后给出UDLR上下左右四种指令,遇到障碍物或者越界的指令会忽略,剩下的继续执行。

    只要到达出口就算找到出口,然后给你一串指令,让你修改指令达到出口,删除或插入任意一个指令花费为1,问让机器人能够找到出口所花费最少。  

    思路:

    感觉很有意思的一道最短路,思路是把每个点分成变成指令长度个点+1,然后就相当于有n^3个点。然后指令是顺序执行的,所以当前点的状态最多到达

    周围可到达点的同一状态。所以我们就可以建边,如果我们走到隔壁点的当前状态就相当于插入了一个指令,就当前点到隔壁点建条花费为1的边。还可以建立

    当前点到当前点的下个状态的边,花费为1,相当于删除当前指令。

    这道题WA了很久= =然后找到数据对拍,最后发现是因为少建了一种边,就是指令执行完了,然后走向下一个点指令执行完了的边没有建立。

    代码:

    /** @xigua */
    #include <cstdio>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <cstring>
    #include <queue>
    #include <set>
    #include <string>
    #include <map>
    #include <climits>
    #include <bitset>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 2e5 + 5;
    const int mod = 1e9 + 7;
    const int INF = 1e8 + 5;
    const ll inf = 1e15 + 5;
    const db eps = 1e-6;
    char mapp[55][55], op[55];
    int dx[] = {1, -1, 0, 0}, dy[] = {0, 0, 1, -1};
    int n, m;
    int cnt, head[maxn], dis[maxn];
    struct Edge {
        int v, w, next;
        bool operator < (const Edge &rhs) const {
            return w > rhs.w;
        }
    } e[maxn*5];
    
    void add(int u, int v, int co) {
        e[cnt].v = v;
        e[cnt].w = co;
        e[cnt].next = head[u];
        head[u] = cnt++;
    }
    
    void init() {
        cnt = 0;
        memset(head, -1, sizeof(head));
    }
    
    void dij(int s, int len) {
        priority_queue<Edge> pq;
        for (int i = 1; i <= len; i++)
            dis[i] = INF;
        bool vis[maxn] = {0};
        dis[s] = 0;
        pq.push((Edge){s, 0});
        while (!pq.empty()) {
            Edge tmp = pq.top(); pq.pop();
            if (vis[tmp.v]) continue;
            vis[tmp.v] = 1;
            for (int i = head[tmp.v]; ~i; i = e[i].next) {
                Edge u = e[i];
                if (dis[u.v] > dis[tmp.v] + u.w) {
                    dis[u.v] = dis[tmp.v] + u.w;
                    pq.push((Edge){u.v, dis[u.v]});
                }
            }
        }
    }
    
    bool safe(int x, int y) {
        return x >= 1 && x <= n && y >= 1 && y <= m && mapp[x][y] != '#';
    }
    
    void solve() {
        while (cin >> n >> m) {
            init();
            for (int i = 1; i <= n; i++)
                scanf("%s", mapp[i] + 1);
            scanf("%s", op+1);
            int len = strlen(op + 1);
            int st, ed;
            for (int i = 1; i <= n; i++) {
                for (int j = 1; j <= m; j++) {
                    if (mapp[i][j] == 'R') st = (i - 1) * m + j;
                    if (mapp[i][j] == 'E') ed = (i - 1) * m + j;
                    if (mapp[i][j] == '#') continue;
                    for (int k = 1; k <= len; k++) {
                        for (int p = 0; p < 4; p++) {
                            int x = i + dx[p];
                            int y = j + dy[p];
                            if (safe(x, y)) {
                                int u = ((i - 1) * m + j) * (len + 1) + k;
                                int v = ((x - 1) * m + y) * (len + 1) + k;
                                add(u, v, 1);
                            }
                        }
                        int x = i, y = j;
                        if (op[k] == 'R') y++;
                        else if (op[k] == 'L') y--;
                        else if (op[k] == 'U') x--;
                        else x++;
                        if (safe(x, y)) {
                            int u = ((i - 1) * m + j) * (len + 1) + k;
                            int v = ((x - 1) * m + y) * (len + 1) + k + 1;
                            add(u, v, 0);
                        }
                        else {
                            int u = ((i - 1) * m + j) * (len + 1) + k;
                            add(u, u + 1, 0);
                        }
                        int u = ((i - 1) * m + j) * (len + 1) + k;
                        add(u, u + 1, 1);
                    }
                    /* 就是这里  没有考虑到建立边 */
                    for (int p = 0; p < 4; p++) {
                        int x = i + dx[p];
                        int y = j + dy[p];
                        if (safe(x, y)) {
                            int u = ((i - 1) * m + j) * (len + 1) + len + 1;
                            int v = ((x - 1) * m + y) * (len + 1) + len + 1;
                            add(u, v, 1);
                        }
                    }
                }
            }
            dij(st * (len + 1) + 1, (n * m + 1) * (len + 1));
            int ans = INF;
            for (int i = 1; i <= len + 1; i++) {
                int cur = ed * (len + 1) + i;
                ans = min(ans, dis[cur]);
            }
            cout << ans << endl;
        }
    }
    
    int main() {
    	int t = 1, cas = 1;
    	//freopen("in.txt", "r", stdin);
    	// freopen("out.txt", "w", stdout);
    	//scanf("%d", &t);
    	while (t--) {
    		// printf("Case %d: ", cas++);
    		solve();
    	}
    	return 0;
    }
    
  • 相关阅读:
    SqlServer 查看数据库中所有存储过程
    SqlServer 查看数据库中所有视图
    SqlServer 查询表的详细信息
    SqlServer 遍历修改字段长度
    net core 操作Redis
    Tuning SharePoint Workflow Engine
    Open With Explorer
    Download language packs for SharePoint 2013
    Change Maximum Size For SharePoint List Template when Saving
    Six ways to store settings in SharePoint
  • 原文地址:https://www.cnblogs.com/ost-xg/p/7138011.html
Copyright © 2011-2022 走看看