HDU 3582

题目:http://acm.hdu.edu.cn/showproblem.php?pid=3582


直接BFS。。但是在标记的不能只标记钥匙和人物坐标,还要标记门的状态。。一开始我把钥匙个数放在最前面,提交的时候一直返回访问越界。。后来把标记写成人物坐标,然后才是钥匙个数和门的状态。。这才AC。。不知道是不是数据有问题。。为什么那样标记就不可以了?坑爹= =!.



下面是AC代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
int n,flag,ex,ey;
char map[15][15];
struct node{
    int cnt;int s;int x,y;
    char map[12][12];
}s_pos;
bool vis[12][12][12][1<<11];
bool cheack(int x,int y){
     return x>=0&&x<n&&y>=0&&y<n;
}
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
void bfs(){
      memset(vis,false,sizeof(vis));
      queue<node > q;
      q.push(s_pos);
      vis[s_pos.x][s_pos.y][s_pos.cnt][s_pos.s]=true;
      while(!q.empty()){
          node now = q.front();  q.pop();
           if(now.x==ex&&now.y==ey){
                flag=1; return ;
           }
          for(int i=0;i<4;i++){
              node next = now; int x=next.x;  int y=next.y;
              x+=dir[i][0],  y+=dir[i][1];
              if(cheack(x,y)){
                  if(map[x][y]=='*')  continue;
                  next.x=x;  next.y=y;

                  if(next.map[x][y]=='K'){
                      next.map[x][y]='.';
                      next.cnt+=1;
                  }
                 if(next.map[x][y]>='a'&&next.map[x][y]<='z'){
                      if(next.cnt>0){
                         next.s|=(1<<(next.map[x][y]-'a'));
                         next.cnt-=1;
                         next.map[x][y]='.';
                      }
                      else continue;
                  }
                  if(!vis[x][y][next.cnt][next.s]){
                      vis[x][y][next.cnt][next.s]=true;
                        q.push(next);
                  }
              }
          }
      }
}
int main(){
    int t;int ca=1;scanf("%d",&t);
    while(t--){
       scanf("%d",&n);
       for(int i=0;i<n;i++)  scanf("%s",map[i]);
       s_pos.cnt=s_pos.s=0;  char temp='a';
       for(int i=0;i<n;i++) for(int j=0;j<n;j++){
              if(map[i][j]=='S')   s_pos.x=i,s_pos.y=j;
              if(map[i][j]=='E')   ex=i,     ey=j;
              if(map[i][j]=='L') {
                s_pos.map[i][j]=temp;
                temp=temp+1;
                continue;
             }
              s_pos.map[i][j]=map[i][j];
       }
       flag=0;
       bfs();
       printf("Case %d: ",ca++);
       if(flag)  printf("Yes\n");
       else      printf("No\n");
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值