• 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
    ",ans);
        else puts("-1");
        return 0;
    }
    View Code
  • 相关阅读:
    5秒解决Https请求 未能创建 SSL/TLS 安全通道
    Entity Framework,EF 手动DB FIRST,不使用设计器
    An item with the same key has already been added
    C#.NET AES ECB 加密
    Linux通过netstat命令统计连接数
    SqlServer 查看某个表的具体数据分布
    SqlServer查看某个表的索引详细信息
    Visual Studio2019 的 Git增加忽略文件
    SQL server 获取各种 约束信息
    C# 根据日期判断星期几
  • 原文地址:https://www.cnblogs.com/wzj-is-a-juruo/p/4633360.html
Copyright © 2020-2023  润新知