• noi 7221 拯救公主 (状态压缩+bfs)


    /*
    这题实在调糊了 借鉴的题解的一些判断方法 位运算大法好 - - 
    因为要集齐所有的宝石所以状态压缩一下
    f[i][j][s]将s化为二进制 每一0表示该宝石没有 1表示该宝石有 
    有:到(i,j)这个点时 宝石收集状况为s的状态是否存在 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    int T,n,m,k,f[210][210][33],sx,sy,ex,ey,num;
    int xx[5]={0,0,0,1,-1};
    int yy[5]={0,1,-1,0,0};
    char s[210][210];
    struct point
    {
        int mx, my, step, sum;
        point (int xx, int yy, int tt, int ss):mx(xx), my(yy), step(tt), sum(ss){};
    };
    struct door
    {
        int xi, yi;
    }door[15];
    bool check(int s)
    {
        int cnt=0;
        for(int i=0;i<=4;i++)
          if((s>>i)&1==1)
            cnt++;
        return(cnt>=k);
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
          {
              memset(f,0,sizeof(f));
              memset(s,0,sizeof(s));
              num=0;
              queue<point> q;
              int falg=0;
              scanf("%d%d%d",&n,&m,&k);
              for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                  {
                    cin>>s[i][j];
                    if(s[i][j]=='S')
                      {
                        s[i][j]='.';
                        sx=i;
                      sy=j;    
                    }
                  if(s[i][j]=='E')
                      {
                        s[i][j]='.';
                        ex=i;
                      ey=j;    
                    }
                  if(s[i][j]=='$')
                    {
                      num++;
                      door[num].xi=i;
                      door[num].yi=j;
                    }
                }
              q.push(point(sx,sy,0,0));
              f[sx][sy][0]=1;//初始状态存在 
              while(!q.empty())
                {
                    point tmmp=q.front();
                    q.pop();
                    int nx=tmmp.mx;
                    int ny=tmmp.my;
                    int su=tmmp.sum;
                    int time=tmmp.step;
                    if(nx==ex&&ny==ey&&check(su))//判断是否符合条件了 
                      {
                          printf("%d
    ",tmmp.step);
                          falg=1;//多组数据害死人啊  一开始return 0 了 
                  }
                if(falg)break;
                if(s[nx][ny]=='.')//一般的情况 直接周围的点入队 
                  for(int i=1;i<=4;i++)
                    {
                        int ox=nx+xx[i];
                        int oy=ny+yy[i];
                        if(ox>0&&ox<=n&&oy>0&&oy<=m&&f[ox][oy][su]==0&&s[ox][oy]!='#')
                          {
                              f[ox][oy][su]=1;
                              q.push(point(ox,oy,time+1,su));
                          }
                    } 
                if(s[nx][ny]=='$')//传送门 把所有传送门周围的点都入队 
                  {
                      for(int i=1;i<=num;i++)
                        for(int j=1;j<=4;j++)
                            {
                              int ox=door[i].xi+xx[j];
                            int oy=door[i].yi+yy[j];
                            if(ox>0&&ox<=n&&oy>0&&oy<=m&&f[ox][oy][su]==0&&s[ox][oy]!='#')
                              {
                                f[ox][oy][su]=1;
                                q.push(point(ox,oy,time+1,su));
                            }
                        }
                  }
                if(s[nx][ny]>='0'&&s[nx][ny]<='4')//开始收集宝石了 
                    {
                      int si=su|(1<< (s[nx][ny]-'0'));//转化出新状态 
                      for(int i=1;i<=4;i++)
                        {
                          int ox=nx+xx[i];
                          int oy=ny+yy[i];
                          if(ox>0&&ox<=n&&oy>0&&oy<=m&&f[ox][oy][si]==0&&s[ox][oy]!='#')    
                            {
                              f[ox][oy][si]=1;
                              q.push(point(ox,oy,time+1,si));
                            }
                        }  
                    }
              }
            if(!falg)
              printf("oop!
    ");
          }
        return 0; 
    }
  • 相关阅读:
    python分析log
    单词长度统计,字符数量统计直方图
    单词计数
    字符替换
    HP Mobile Center 1.01 Related System Requirements
    字符统计
    文件复制
    C语言,不是从hello world开始
    最近
    echarts Map(地图) 不同颜色区块显示
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5478865.html
Copyright © 2020-2023  润新知