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
  • 相关阅读:
    MySQL教程(四)—— MySQL的登录与退出
    MySQL教程(三)—— MySQL的安装与配置
    django中使用POST方法报错 URL via POST, but the URL doesn't end in a slash
    django的html模板中获取字典的值
    使用pycharm手动搭建python语言django开发环境(五) 使用日志模块打日志
    使用pycharm手动搭建python语言django开发环境(四) django中buffer类型与str类型的联合使用
    python语言 buffer类型数据的使用 'ascii' codec can't decode byte 0xe5 问题的解决
    使用pycharm手动搭建python语言django开发环境(三) 使用django的apps应用 添加应用静态文件
    使用pycharm手动搭建python语言django开发环境
    使用pycharm手动搭建python语言django开发环境(一)
  • 原文地址:https://www.cnblogs.com/heimao5027/p/5978481.html
Copyright © 2011-2022 走看看