zoukankan      html  css  js  c++  java
  • FZU 2124 吃豆人 bfs

    题目链接:吃豆人

    比赛的时候写的bfs,纠结要不要有vis数组设置已被访问,没有的话死循环,有的话就不一定是最优解了。【此时先到的不一定就是时间最短的。】于是换dfs,WA。

    赛后写了个炒鸡聪明的dfs,TLE,才发现时间复杂度好像是4^(n*m)。T_T

    依然感觉这个dfs很棒。

    bfs已AC,怎么解决的这个问题呢,如果当前位置next 被优化了则加入队列,以此优化其他位置,否则不加入队列。T_T好有道理~~~

    感觉bfs和dfs好神奇的说~

    dfs TLE代码:

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <cmath>
    #include <queue>
    #define inf 100000000
    using namespace std;
    
    char mp[30][30];
    
    struct Node{
        int x, y;
    }st, ed, tool, temp, nxt;
    
    int vis[30][30];
    double step[30][30];
    int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
    int n, m;
    
    bool check(Node temp) {
        if (temp.x >= 0 && temp.x < n && temp.y >= 0 && temp.y < m && !vis[temp.x][temp.y] && mp[temp.x][temp.y] != 'X') {
            return true;
       )}
        return false;
    }
    
    void get(Node temp, Node ed) {
        if (temp.x == ed.x) {
            int minn = min(temp.y, ed.y);
            int maxm = max(temp.y, ed.y);
            for (int i=minn+1; i<maxm; ++i) {
                if (mp[ed.x][i] == 'X' || mp[ed.x][i] == 'S') return;
            }
            int t = abs(temp.y - ed.y);
            step[ed.x][ed.y] = min(step[temp.x][temp.y]+t*0.2,step[ed.x][ed.y]);
        }
        else if (temp.y == ed.y) {
            int minn = min(temp.x, ed.x);
            int maxm = max(temp.x, ed.x);
            for (int i=minn+1; i<maxm; ++i) {
                if (mp[i][ed.y] == 'X' || mp[i][ed.x] == 'S') return;
            }
            int t = abs(temp.x - ed.x);
            step[ed.x][ed.y] = min(step[temp.x][temp.y]+t*0.2, step[ed.x][ed.y]);
        }
    }
    
    void dfs(Node st, Node ed, bool v) {
        for (int i=0; i<4; ++i) {
        nxt.x = st.x + dir[i][0];
        nxt.y = st.y + dir[i][1];
        if (check(nxt)) {
            double t = step[st.x][st.y];
            if (v) t += 0.5;
                else t += 1;
            step[nxt.x][nxt.y] = min(step[nxt.x][nxt.y], t);
            vis[nxt.x][nxt.y] = 1;
            get(nxt, ed);
            if (nxt.x == tool.x && nxt.y == tool.y) dfs(nxt, ed, true);
            else dfs(nxt, ed, v);
          }
        }
       vis[st.x][st.y] = 0;
       return;
    }
    
    int main() {
        while(~scanf("%d%d", &n, &m)) {
            bool v = false;
            memset(vis, 0, sizeof(vis));
            for (int i=0; i<n; ++i) {
                for (int j=0; j<m; ++j) {
                    step[i][j] = inf;
                }
            }
            getchar();
            for (int i=0; i<n; ++i) {
                for (int j=0; j<m; ++j) {
                    scanf("%c", &mp[i][j]);
                    if (mp[i][j] == 'P') {
                        st.x = i, st.y = j;
                    }
                    else if (mp[i][j] == 'B') {
                        ed.x = i, ed.y = j;
                    }
                    else if (mp[i][j] == 'S') {
                        tool.x = i, tool.y = j;
                    }
                }
                if (i != n-1) scanf("
    ");
            }
            step[st.x][st.y] = 0;
            vis[st.x][st.y] = 1;
            dfs(st, ed, v);
            get(st, ed);
            double ans = step[ed.x][ed.y];
            if (ans != inf)
                printf("%.1lf
    ", ans);
           else printf("-1
    ");
        }
        return 0;
    }

    bfs AC 代码:

    /*
    直接一个bfs,用两个数组保存有工具和没有工具时需要的时间。
    */
    
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <queue>
    #define inf 1000000000
    using namespace std;
    
    char mp[30][30];
    int n, m;
    
    struct Node {
        int x, y, s; // 0 表示没有工具 1 表示有工具了。
    }st, ed, temp, now, nxt;
    
    int step[30][30][2];
    
    int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1};
    
    void bfs(Node st) {
        queue<Node> que;
        que.push(st);
        step[st.x][st.y][0] = 0;
        while(!que.empty()) {
            now = que.front();
            que.pop();
            if (now.x == ed.x) {
                int miny = min(now.y, ed.y);
                int maxy = max(now.y, ed.y);
                bool get = true;
                for (int y=miny+1; y<maxy; ++y) {
                    if (mp[now.x][y] == 'X' || mp[now.x][y] == 'S') {
                            get = false;
                            break;
                    }
                }
                if (get) step[ed.x][ed.y][now.s] = min(step[now.x][now.y][now.s] + 2 * (maxy - miny), step[ed.x][ed.y][now.s]);
            }
    
            if (now.y == ed.y) {
                int minx = min(now.x, ed.x);
                int maxx = max(now.x, ed.x);
                bool get = true;
                for (int x=minx+1; x<maxx; ++x) {
                    if (mp[x][ed.y] == 'X' || mp[x][ed.y] == 'S') {
                        get = false;
                    }
                }
                if (get) step[ed.x][ed.y][now.s] = min(step[now.x][now.y][now.s]  + 2 * (maxx - minx), step[ed.x][ed.y][now.s]);
            }
    
            int T;
            for (int i=0; i<4; ++i) {
                nxt.x = now.x + dir[i][0];
                nxt.y = now.y + dir[i][1];
                nxt.s = now.s;
                if (nxt.x<0 || nxt.y<0 || nxt.x>=n || nxt.y>=m) continue;
                if (mp[nxt.x][nxt.y] == 'X') continue;
                if (now.s) T = 5;
                else T = 10;
                if (step[nxt.x][nxt.y][nxt.s] > step[now.x][now.y][now.s] + T) {
                    step[nxt.x][nxt.y][nxt.s] = step[now.x][now.y][now.s] + T;
                    if (mp[nxt.x][nxt.y] == 'S') {
                        nxt.s = 1;
                        step[nxt.x][nxt.y][1] = step[nxt.x][nxt.y][0];
                    }
                    que.push(nxt);
                }
            }
        }
    }
    
    
    
    
    int main() {
        while(cin >> n >> m) {
            for (int i=0; i<n; ++i) {
                for (int j=0; j<m; ++j) {
                    for (int k=0; k<2; ++k) {
                        step[i][j][k] = inf;
                    }
                }
            }
    
            for (int i=0; i<n; ++i) {
                for (int j=0; j<m; ++j) {
                    cin >> mp[i][j];
                    if (mp[i][j] == 'P') {
                        st.x = i, st.y = j;
                    }
                    else if (mp[i][j] == 'B') {
                        ed.x = i, ed.y = j;
                    }
                }
            }
    
            st.s = 0;
            bfs(st);
            int ans = min(step[ed.x][ed.y][0], step[ed.x][ed.y][1]);
            if (ans == inf) cout << "-1
    ";
            else printf("%.1lf
    ", ans*1.0/10);
        }
        return 0;
    }
    

      

  • 相关阅读:
    WCF 第八章 安全 确定替代身份(中)使用AzMan认证
    WCF 第八章 安全 总结
    WCF 第八章 安全 因特网上的安全服务(下) 其他认证模式
    WCF Membership Provider
    WCF 第八章 安全 确定替代身份(下)模仿用户
    WCF 第八章 安全 因特网上的安全服务(上)
    WCF 第九章 诊断
    HTTPS的七个误解(转载)
    WCF 第八章 安全 日志和审计
    基于比较的排序算法集
  • 原文地址:https://www.cnblogs.com/icode-girl/p/5342585.html
Copyright © 2011-2022 走看看