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;
    }
    
  • 相关阅读:
    eclipse在线安装mybatis generator插件、及插件的使用
    Oracle 的SID 与 Service_Name 区别
    Mybatis generator 配置报错
    Mybatis generator 生成Javabean报错:Table configuration with catalog null, schema public, and table globalpage did not resolve to any tables
    pom.xml中添加oracle数据库驱动包报错: Missing artifact com.oracle:ojdbc14:jar:10.2.0.4.0
    Eclipse中10个最有用的快捷键组合
    Spring Tool Suite 配置和使用
    【搜索】【动态规划】【杂题】——洛谷P1514.引水入城
    c++ 矩阵求逆
    LNK1104 无法打开文件 exe
  • 原文地址:https://www.cnblogs.com/ost-xg/p/7138011.html
Copyright © 2011-2022 走看看