zoukankan      html  css  js  c++  java
  • bfs UESTC 381 Knight and Rook

    http://acm.uestc.edu.cn/#/problem/show/381

    题目大意:给你两个棋子:车、马,再给你一个n*m的网格,从s出发到t,你可以选择车或者选择马开始走,图中有一些障碍物,该障碍物是不能走的,走的图中有换一次棋子的机会,问最少需要几次能从s走到t?

    思路:bfs来4次就好了。两次记录从s->t,两次是t->s。然后暴力一下就出来了,复杂度为4*n*m*log

    //看看会不会爆int!数组会不会少了一维!
    //取物问题一定要小心先手胜利的条件
    #include <bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define ALL(a) a.begin(), a.end()
    #define pb push_back
    #define mk make_pair
    #define fi first
    #define se second
    #define haha printf("haha
    ")
    const int maxn = 100 + 5;
    const int inf = 0x3f3f3f3f;
    char ch[maxn][maxn];
    int n, m;
    pair<int, int> s, t;
    int rook[maxn][maxn], knight[maxn][maxn];
    int r1[maxn][maxn], k1[maxn][maxn];
    int r2[maxn][maxn], k2[maxn][maxn];
    int dx[] = {-2, -2, -1, 1, 2, 2, 1, -1};
    int dy[] = {-1, 1, 2, 2, 1, -1, -2, -2};
    
    int bfs1(int a, int b){
        memset(rook, 0x3f, sizeof(rook));
        queue<pair<int, int> > que;
        que.push(mk(a, b));
        rook[a][b] = 0;
        while (!que.empty()){
            pair<int, int> p = que.front(); que.pop();
            int x = p.fi, y = p.se;
            ///if (flag && x == s.fi && y == s.se) break;
            int lb = 0, rb = 0;
            for (int i = x - 1; i > 0; i--)
                if (ch[i][y] == '#') {lb = i; break;}
            for (int i = x; i <= n; i++)
                if (ch[i][y] == '#') {rb = i; break;}
            if (rb == 0) rb = n + 1;
            ///lb和rb都是不能走的
            for (int i = lb + 1; i < rb; i++){
                if (i != x && rook[i][y] > rook[x][y] + 1){
                    rook[i][y] = rook[x][y] + 1;
                    que.push(mk(i, y));
                }
            }
            lb = 0, rb = 0;
            for (int i = y - 1; i > 0; i--)
                if (ch[x][i] == '#') {lb = i; break;}
            for (int i = y; i <= m; i++)
                if (ch[x][i] == '#') {rb = i; break;}
            if (rb == 0) rb = m + 1;
            for (int i = lb + 1; i < rb; i++){
                if (i != y && rook[x][i] > rook[x][y] + 1){
                    rook[x][i] = rook[x][y] + 1;
                    que.push(mk(x, i));
                }
            }
        }
        return rook[s.fi][s.se];
    }
    
    int bfs2(int a, int b){
        memset(knight, 0x3f, sizeof(knight));
        queue<pair<int, int> > que;
        que.push(mk(a, b));
        knight[a][b] = 0;
        while (!que.empty()){
            pair<int, int> p = que.front(); que.pop();
            int x = p.fi, y = p.se;
            ///if (flag && x == s.fi && y == s.se) break;
            for (int i = 0; i < 8; i++){
                int nx = x + dx[i], ny = y + dy[i];
                if (nx <= 0 || ny <= 0 || nx > n || ny > m) continue;
                if (ch[nx][ny] == '#') continue;
                if (knight[nx][ny] > knight[x][y] + 1){
                    knight[nx][ny] = knight[x][y] + 1;
                    que.push(mk(nx, ny));
                }
            }
        }
        return rook[s.fi][s.se];
    }
    
    int solve(){
        //printf("k = %d r = %d
    ", k[s.fi][s.se], r[s.fi][s.se]);
        //int mini = min(r2[t.fi][t.se], k2[t.fi][t.se]);
        int mini = inf;
        for (int i = 1; i <= n; i++){
            for (int j = 1; j <= m; j++){
                if (ch[i][j] == '#') continue;
                if (r1[i][j] < inf && k2[i][j] < inf) mini = min(mini, r1[i][j] + k2[i][j]);
                if (k1[i][j] < inf && r2[i][j] < inf) mini = min(mini, k1[i][j] + r2[i][j]);
            }
        }
        if (mini == inf) return -1;
        return mini;
    }
    
    int main(){
        int T; cin >> T;
        for (int kase = 1; kase <= T; kase++){
            cin >> n >> m;
            for (int i = 1; i <= n; i++){
                scanf("%s", ch[i] + 1);
                for (int j = 1; j <= m; j++){
                    if (ch[i][j] == 's') s = mk(i, j);
                    if (ch[i][j] == 't') t = mk(i, j);
                }
            }
            memset(r1, inf, sizeof(r1)); memset(k1, inf, sizeof(k1));
            memset(r2, inf, sizeof(r2)); memset(k2, inf, sizeof(k2));
            bfs1(t.fi, t.se); bfs2(t.fi, t.se);
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= m; j++)
                    r1[i][j] = rook[i][j], k1[i][j] = knight[i][j];
            bfs1(s.fi, s.se); bfs2(s.fi, s.se);
            for (int i = 1; i <= n; i++)
                for (int j = 1; j <= m; j++)
                    r2[i][j] = rook[i][j], k2[i][j] = knight[i][j];
            printf("Case #%d: %d
    ", kase, solve());
        }
        return 0;
    }
    View Code
  • 相关阅读:
    openwrt 相关文章
    负载均衡相关文章
    Today's Progress
    Rodrigues formula is beautiful, but uneven to sine and cosine. (zz Berkeley's Page)
    Camera Calibration in detail
    Fundamental Matrix in Epipolar
    Camera Calibration's fx and fy do Cares in SLAM
    FilterEngine::apply
    FilterEngine 类解析——OpenCV图像滤波核心引擎(zz)
    gaussBlur
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5978481.html
Copyright © 2011-2022 走看看