/*
这题实在调糊了 借鉴的题解的一些判断方法 位运算大法好 - -
因为要集齐所有的宝石所以状态压缩一下
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[][][],sx,sy,ex,ey,num;
int xx[]={,,,,-};
int yy[]={,,-,,};
char s[][];
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[];
bool check(int s)
{
int cnt=;
for(int i=;i<=;i++)
if((s>>i)&==)
cnt++;
return(cnt>=k);
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(f,,sizeof(f));
memset(s,,sizeof(s));
num=;
queue<point> q;
int falg=;
scanf("%d%d%d",&n,&m,&k);
for(int i=;i<=n;i++)
for(int j=;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,,));
f[sx][sy][]=;//初始状态存在
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\n",tmmp.step);
falg=;//多组数据害死人啊 一开始return 0 了
}
if(falg)break;
if(s[nx][ny]=='.')//一般的情况 直接周围的点入队
for(int i=;i<=;i++)
{
int ox=nx+xx[i];
int oy=ny+yy[i];
if(ox>&&ox<=n&&oy>&&oy<=m&&f[ox][oy][su]==&&s[ox][oy]!='#')
{
f[ox][oy][su]=;
q.push(point(ox,oy,time+,su));
}
}
if(s[nx][ny]=='$')//传送门 把所有传送门周围的点都入队
{
for(int i=;i<=num;i++)
for(int j=;j<=;j++)
{
int ox=door[i].xi+xx[j];
int oy=door[i].yi+yy[j];
if(ox>&&ox<=n&&oy>&&oy<=m&&f[ox][oy][su]==&&s[ox][oy]!='#')
{
f[ox][oy][su]=;
q.push(point(ox,oy,time+,su));
}
}
}
if(s[nx][ny]>=''&&s[nx][ny]<='')//开始收集宝石了
{
int si=su|(<< (s[nx][ny]-''));//转化出新状态
for(int i=;i<=;i++)
{
int ox=nx+xx[i];
int oy=ny+yy[i];
if(ox>&&ox<=n&&oy>&&oy<=m&&f[ox][oy][si]==&&s[ox][oy]!='#')
{
f[ox][oy][si]=;
q.push(point(ox,oy,time+,si));
}
}
}
}
if(!falg)
printf("oop!\n");
}
return ;
}

最新文章

  1. C语言的可变参数在Linux(Ubuntu)与Windows下注意点
  2. vue.js学习之入门实例
  3. 微信开发之.Net
  4. 关于 SSV-ID: 4474 POC的分析和思考
  5. HDOJ 4389 X mod f(x)
  6. 【ACM】hud1166 敌兵布阵(线段树)
  7. 什么是响应式Web设计?怎样进行?
  8. 12-26 tableView的学习心得
  9. python3_mechanicalsoup
  10. MTK6515 android打版软件配置(DrvGen.exe 使用)
  11. C++指针和引用
  12. Transform java future into completable future 【将 future 转成 completable future】
  13. Redis sentinel 哨兵模式集群方案配置
  14. react入门到进阶(一)
  15. 设计模式成长记(一) 抽象工厂模式(Abstract Factory)
  16. 【线段树】【BZOJ1798】【AHOI2009】维护序列
  17. vmware安装centOs操作系统配置网络的一系列问题
  18. php如何实现图片点击下载,并保存本地?-----本例子为二维码的生成图片,并支持点击下载
  19. RBAC功能模块
  20. 图的关键路径,AOE,完整实现,C++描述

热门文章

  1. 在iOS7中修改状态栏字体的颜色-b
  2. 用硬件(Verilog)实现二进制码和格雷码的转换
  3. 发一下关于公司的HOUSE OF HELLO 关于假货网站的声明吧
  4. 【Linux】基础配置-修改命令提示符的风格
  5. GNU PID
  6. 关于用POI和EXCEL交互的问题
  7. 深入浅出 Java Concurrency (4): 原子操作 part 3 指令重排序与happens-before法则
  8. STL容器介绍(转)
  9. Integer Intervals(贪心)
  10. POJ 3180 The Cow Prom(强联通)