COJ 拯救瑞恩

 

试题描述
在n行n列的字符方阵中I表示“我”最初所在位置,R是大兵瑞恩所在位置。4<n<11。
“我”从当前位置可以向上、或下、或左、或右移动一格,只要新点无障碍且未出界。
标有“.”的位置可以通过,标有“*”的位置是障碍物,不能到达和通过。
标有字母A~G的位置代表“门”,是有条件的障碍物,1~7依次是A~G的钥匙。
走到某个门时,若已走路径未经过其钥匙,则门视为“*”,若已经过其钥匙则视为“.”。
求“我”到达瑞恩的位置至少要走多少步?若无法到达输出-1。
输入
输入文件SAVE.IN中共n行n列字符,均为题目所述的字符。字符间无空格。
输出
输出文件SAVE.OUT中仅有答案一个整数。
输入示例
6
......
......
.I.3..
.**2*.
.**1*C
.A*R*B
输出示例
27

设状态为(x,y,S)表示当前在(x,y),拥有的钥匙集合为S,BFS即可。

#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define ren for(int i=first[x];i!=-1;i=next[i])
using namespace std;
inline int read() {
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}
struct Arr {int x,y,S;};
char A[12][12];
int n,vis[12][12][1<<8],d[12][12][1<<8];
const int mx[]={1,-1,0,0},my[]={0,0,1,-1};
queue<Arr> Q;
void bfs(int x,int y,int S) {
     vis[x][y][S]=1;Q.push((Arr){x,y,S});
     while(!Q.empty()) {
         x=Q.front().x;y=Q.front().y;S=Q.front().S;Q.pop();
         rep(dir,0,3) {
             int x2=x+mx[dir],y2=y+my[dir],S2=S;
             if(x2<1||x2>n||y2<1||y2>n) continue;
             if(A[x2][y2]=='*') continue;
             if(isdigit(A[x2][y2])&&!(S&(1<<(A[x2][y2]-'1')))) continue;
             if(isalpha(A[x2][y2])) S2|=(1<<(A[x2][y2]-'A'));
             if(!vis[x2][y2][S2]) {
                 vis[x2][y2][S2]=1;
                 d[x2][y2][S2]=d[x][y][S]+1;
                 Q.push((Arr){x2,y2,S2});                     
             }
         }            
     }
}
int main() {
    int x1,x2,y1,y2;
    n=read();
    rep(i,1,n) scanf("%s",A[i]+1);
    rep(i,1,n) rep(j,1,n) {
        if(A[i][j]=='I') x1=i,y1=j,A[i][j]='.';
        if(A[i][j]=='R') x2=i,y2=j,A[i][j]='.';            
    }
    bfs(x1,y1,0);
    int ans=1e9;
    rep(S,0,1<<7) if(vis[x2][y2][S]) ans=min(ans,d[x2][y2][S]);
    if(ans!=1e9) printf("%d\n",ans);
    else puts("-1");
    return 0;
}
View Code

 

posted @ 2015-07-09 15:45  wzj_is_a_juruo  阅读(194)  评论(0编辑  收藏  举报