当前位置:编程学习 > C/C++ >>

HDU 1429 胜利大逃亡(续) (BFS + 状态压缩)

好好的一道题,又被我搞废了

中文题目题意就不用说了。把钥匙的有无情况状态压缩:01代表有1号钥匙,10代表有2号钥匙,11代表有1号和2号钥匙...................................................................

思维错在两点,弄了一上午:

1. 判断点是否入队,除去最前提的条件,还有就是该点的状态是否更新了(即为是否拿了某把钥匙),更新后的状态未出现过就能入队............一开始没有考虑状态问题直接入队,会有在两个点中走来走去的re情况。

2.同样的钥匙可能有多把,一开始写法是碰到已经拿过的钥匙,该点不入队,这样就会出现问题:如果刚好到达终点的这条路上有同样的钥匙,那就变成不能到达了。

所以重复的钥匙不需要多考虑。

 

#include <cstdio>   
#include <iostream>   
#include <cmath>   
#include <cstring>   
#include <algorithm>   
using namespace std;  
int n,m,head,tail,T;  
char map[33][33];  
int dp[33][33][1 << 10];  
int dirx[] = {1,-1,0,0};  
int diry[] = {0,0,1,-1};  
struct node {  
    int x,y;  
    int buff;  
} q[1111111],st,end;  
  
void init() {  
    memset(dp,-1,sizeof(dp));  
    head = 0;  
    tail = 0;  
}  
  
bool go(int x,int y) {  
    if(x < 0 || x >= n || y < 0 || y >= m) return false;  
    if(map[x][y] == '*') return false;  
    return true;  
}  
int bfs() {  
    q[head++] = st;  
    dp[st.x][st.y][st.buff] = 0;  
    while(head != tail) {  
        node t = q[tail++];  
        node tt ;  
        if(t.x == end.x && t.y == end.y) {  
            if(T > dp[t.x][t.y][t.buff]) return dp[t.x][t.y][t.buff];  
            else return -1;  
        }  
        if(dp[t.x][t.y][t.buff] >= T) return -1;  
        for(int i=0; i<4; i++) {  
            tt.x = t.x + dirx[i];  
            tt.y = t.y + diry[i];  
            tt.buff = t.buff;  
            if(go(tt.x,tt.y)) {  
                if(map[tt.x][tt.y] >='A' && map[tt.x][tt.y] <='J') {  
                    int move = map[tt.x][tt.y] - 'A';  
                    if(((t.buff >> move) &  1) == 0) continue;  
  
                } else if(map[tt.x][tt.y] >= 'a' && map[tt.x][tt.y] <='j') {  
                    int move = map[tt.x][tt.y] - 'a';  
                    // if((t.buff >> move) & 1) continue;  //此处不应该考虑的    
                    tt.buff = t.buff | (1 << move);  
                }  
                if(dp[tt.x][tt.y][tt.buff] == -1) {  
                    dp[tt.x][tt.y][tt.buff] = dp[t.x][t.y][t.buff] + 1;  
                    q[head++] = tt;  
                }  
            }  
        }  
    }  
    return -1;  
}  
int main() {  
    while(scanf("%d%d%d",&n,&m,&T) != EOF) {  
        init();  
        for(int i=0; i<n; i++) scanf("%s",map[i]);  
        for(int i=0; i<n; i++)  
            for(int j=0; j<m; j++) {  
                if(map[i][j] == '@') {  
                    st.x = i;  
                    st.y = j;  
                    st.buff = 0;  
                }  
                if(map[i][j] == '^') {  
                    end.x = i;  
                    end.y = j;  
                    end.buff = 0;  
                }  
            }  
        printf("%d\n",bfs());  
    }  
    return 0;  
}  

 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,