zoukankan      html  css  js  c++  java
  • 拯救大兵瑞恩 HDU

    拯救大兵瑞恩

    思路:钥匙种类p = 10,我们可以拥有不同种类钥匙,通过这个我们可以把图分成2^p层,表示拥有不同种类钥匙的情况。

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    
    using namespace std;
    
    const int N = 17;
    int mv_x[] = {1, -1, 0, 0};
    int mv_y[] = {0, 0, -1, 1};
    int mp[N][N][N][N]; //地图相通情况
    int key[N][N]; //钥匙分配情况
    int step[1 << 11][N][N]; //分层图
    int n, m, p, k, s; 
    
    struct node{
        int x, y, lev;
    };
    
    bool check(int x, int y){
        return x >= 1 && x <= n && y >= 1 && y <= m;
    }
    
    void bfs(){
        queue<node > que;
        que.push({1, 1, 0});
        step[0][1][1] = 0;
    
        while(!que.empty()){
            node now = que.front();
            que.pop();
            int lev = now.lev;
            for(int p = 0; p < 4; ++p){
                int dx = now.x + mv_x[p];
                int dy = now.y + mv_y[p];
                //越界
                if(!check(dx, dy)) continue;
                //走过了
                if(step[lev][dx][dy] != -1) continue;
                int info = mp[now.x][now.y][dx][dy];
                //是墙
                if(info == 0) continue;
                //需要钥匙
                if(info != -1){
                    //没这类钥匙
                    if((lev | (1 << (info - 1))) != lev) continue;
                    //有这类钥匙
                    step[lev][dx][dy] = step[lev][now.x][now.y] + 1;
                    que.push({dx, dy, lev});
                    //下一步有钥匙
                    if(key[dx][dy]){
                        //捡起钥匙
                        step[lev | key[dx][dy]][dx][dy] = step[lev][dx][dy];
                        que.push({dx, dy, lev | key[dx][dy]});
                    }
                }else{
                    //不需要钥匙
                    step[lev][dx][dy] = step[lev][now.x][now.y] + 1;
                    que.push({dx, dy, lev});
                    //下一步有钥匙
                    if(key[dx][dy]){
                        //捡起钥匙
                        step[lev | key[dx][dy]][dx][dy] = step[lev][dx][dy];
                        que.push({dx, dy, lev | key[dx][dy]});
                    }                
                }
            }
    
        }
    }
    
    void solve(){
    
        while(~scanf("%d%d%d%d", &n, &m, &p, &k)){
            memset(mp, -1, sizeof(mp));
            memset(key, 0, sizeof(key));
            memset(step, -1, sizeof(step));
            
            int x1, x2, y1, y2, g;
            for(int i = 0; i < k; ++i){
                scanf("%d%d%d%d%d", &x1, &y1, &x2, &y2, &g);
                mp[x1][y1][x2][y2] = g;
                mp[x2][y2][x1][y1] = g;
            }
            scanf("%d", &s);
            for(int i = 0; i < s; ++i){
                scanf("%d%d%d", &x1, &y1, &g);
                key[x1][y1] |= (1 << (g - 1));
            }
    
            bfs();
            int ans = 1e9;
            for(int i = 0; i <= 1030; ++i){
    
                if(step[i][n][m] == -1) continue;
    
                ans = min(ans, step[i][n][m]);
            }
    
            printf("%d
    ", ans == 1e9 ? -1 : ans);
        }
    }
    
    int main(){
        
        solve();    
        //cout << "not error" << endl;
        return 0;
    }
  • 相关阅读:
    10.01 简单的51代码
    1010Linux的文件操作函数以及所需头文件
    10.05 最初对Linux的了解,对Shell的认识
    1006 Linux的基本命令以及一些简单的通配符说明
    10.03 简单的51单片机程序
    1011Linux用户管理规则及用户管理函数
    vim命令以及gcc编译器的常用cmd
    10.02 一个简单的串口的初始化程序
    做销售的100个绝招
    一个女程序员的创业人生:胆识也是一种能力
  • 原文地址:https://www.cnblogs.com/SSummerZzz/p/12986858.html
Copyright © 2011-2022 走看看