zoukankan      html  css  js  c++  java
  • poj2312 Battle City 【暴力 或 优先队列+BFS 或 BFS】

    题意:M行N列的矩阵。Y:起点,T:终点。S、R不能走,走B花费2,走E花费1.求Y到T的最短时间。

    三种解法。♪(^∇^*)

    //解法一:暴力

    //157MS
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int N = 305;
    int a[N][N], b[N][N];
    char s[N][N];
    int m, n;
    
    int main() {
        int i, j;
        while(~scanf("%d%d", &m, &n), n || m) {
            getchar();
            int sx, sy, ex, ey;
            for(i = 0; i < m; ++i) scanf("%s", s[i]);
            for(i = 0; i < m; ++i) {
                for(j = 0; j < n; ++j) {
                    if(s[i][j] == 'R' || s[i][j] == 'S')
                        a[i][j] = inf;
                    else if(s[i][j] == 'B')
                        a[i][j] = 2;
                    else  a[i][j] = 1;
                    if(s[i][j] == 'Y') {sx = i; sy = j;}
                    else if(s[i][j] == 'T') {ex = i; ey = j;}
                }
            }
            CLR(b, inf);
            b[sx][sy] = 0;
            while(1) {
                bool f = 0;
                for(i = 0; i < m; ++i) {
                    for(j = 0; j < n; ++j) {
                        if(b[i][j] == inf) continue;
                        if(i > 0 && b[i-1][j] > b[i][j] + a[i-1][j]) {
                            b[i-1][j] = b[i][j] + a[i-1][j];
                            f = 1;
                        }
                        if(i < m-1 && b[i+1][j] > b[i][j] + a[i+1][j]) {
                            b[i+1][j] = b[i][j] + a[i+1][j];
                            f = 1;
                        }
                        if(j > 0 && b[i][j-1] > b[i][j] + a[i][j-1]) {
                            b[i][j-1] = b[i][j] + a[i][j-1];
                            f = 1;
                        }
                        if(j < n-1 && b[i][j+1] > b[i][j] + a[i][j+1]) {
                            b[i][j+1] = b[i][j] + a[i][j+1];
                            f = 1;
                        }
                    }
                }
                if(!f) break;
            }
            if(b[ex][ey] != inf) printf("%d
    ", b[ex][ey]);
            else printf("-1
    ");
        }
        return 0;
    }

    //解法二:bfs+优先队列

    //16MS
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int N = 305;
    struct node {
        int x, y;
        int w;
        node(int x = 0, int y = 0, int w = 0):x(x),y(y),w(w){}
        bool operator < (const node&r) const {
            return w > r.w;
        }
    };
    char s[N][N];
    bool vis[N][N];
    int dx[] = {1,0,-1,0};
    int dy[] = {0,1,0,-1};
    int m, n;
    int ans;
    int sx, sy;
    bool check(int x, int y) {
        if(x < 0 || x >= m || y < 0 || y >= n)
            return false;
        if(s[x][y] == 'S' || s[x][y] == 'R' || vis[x][y])
            return false;
        return true;
    }
    int bfs() {
        CLR(vis, 0);
        priority_queue<node> q;
        q.push(node(sx, sy, 0));
        vis[sx][sy] = 1;
        while(!q.empty()) {
            node t = q.top(); q.pop();
            //vis[t.x][t.y] = 0;
            if(s[t.x][t.y] == 'T') {
                ans = t.w;
                return true;
            }
            for(int i = 0; i < 4; ++i) {
                int x = t.x + dx[i];
                int y = t.y + dy[i];
                if(check(x, y)) {
                    int w = t.w + 1;
                    if(s[x][y] == 'B') w++;
                    vis[x][y] = 1;
                    q.push(node(x, y, w));
                }
            }
        }
        return false;
    }
    int main() {
        int i, j;
        while(~scanf("%d%d", &m, &n), n || m) {
            getchar();
            for(i = 0; i < m; ++i) scanf("%s", s[i]);
            for(i = 0; i < m; ++i) {
                for(j = 0; j < n; ++j) {
                    if(s[i][j] == 'Y') {sx = i; sy = j; break;}
                }
            }
            if(bfs()) printf("%d
    ", ans);
            else printf("-1
    ");
        }
        return 0;
    }

    //解法三:bfs,不用优先队列,搜到B时,把它变换成E再放入队列,重新取下一个队首继续搜索,这样就不用优先队列,用普通队列也能做啦

    //32MS
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<string>
    #include<cmath>
    #include<queue>
    #include<limits.h>
    #define CLR(a,b) memset((a),(b),sizeof((a)))
    using namespace std;
    typedef long long ll;
    const int inf = 0x3f3f3f3f;
    const int mod = 1e9+7;
    const int N = 305;
    struct node {
        int x, y;
        int w;
        node(int x = 0, int y = 0, int w = 0):x(x),y(y),w(w){}
    };
    char s[N][N];
    bool vis[N][N];
    int dx[] = {1,0,-1,0};
    int dy[] = {0,1,0,-1};
    int m, n;
    int ans;
    int sx, sy;
    bool check(int x, int y) {
        if(x < 0 || x >= m || y < 0 || y >= n)
            return false;
        if(s[x][y] == 'S' || s[x][y] == 'R' || vis[x][y])
            return false;
        return true;
    }
    int bfs() {
        CLR(vis, 0);
        queue<node> q;
        q.push(node(sx, sy, 0));
        vis[sx][sy] = 1;
        while(!q.empty()) {
            node t = q.front(); q.pop();
            if(s[t.x][t.y] == 'T') {
                ans = t.w;
                return true;
            }
            if(s[t.x][t.y] == 'B') {
                t.w++;
                s[t.x][t.y] = 'E';
                q.push(t);
                continue;
            }
            for(int i = 0; i < 4; ++i) {
                int x = t.x + dx[i];
                int y = t.y + dy[i];
                if(check(x, y)) {
                    int w = t.w + 1;
                    vis[x][y] = 1;
                    q.push(node(x, y, w));
                }
            }
        }
        return false;
    }
    int main() {
        int i, j;
        while(~scanf("%d%d", &m, &n), n || m) {
            getchar();
            for(i = 0; i < m; ++i) scanf("%s", s[i]);
            for(i = 0; i < m; ++i) {
                for(j = 0; j < n; ++j) {
                    if(s[i][j] == 'Y') {sx = i; sy = j; break;}
                }
            }
            if(bfs()) printf("%d
    ", ans);
            else printf("-1
    ");
        }
        return 0;
    }
  • 相关阅读:
    .NET[C#]使用LINQ从List<T>集合中获取最后N条数据记录的方法有哪些?
    这个匿名对象没有实现IComparable接口
    c/c++中define用法详解及代码示例
    几个常用Json组件的性能测试
    通过jQuery Ajax使用FormData对象上传文件
    《631962 揭秘Java虚拟机-JVM设计原理与实现.pdf【第8章】》 ——类方法解析
    《631962 揭秘Java虚拟机-JVM设计原理与实现.pdf【第7章】》 ——Java栈桢
    《OOP-Klass》
    《631962 揭秘Java虚拟机-JVM设计原理与实现.pdf【第6章】》——类变量解析
    《631962 揭秘Java虚拟机-JVM设计原理与实现.pdf【第5章】》——常量池解析
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/6716380.html
Copyright © 2011-2022 走看看