点击打开链接

题意:从K走到T,S为怪,走的时候就多花费一秒,走到T时收集m把不同的钥匙。可是规定收集n之前,必须1~n-1所有收集完成,怪最多有5个

思路:怪最多就有5个,然后钥匙是1~9把,我们每一个点的状态就不会非常多,在BFS时每一个点的状态进行标记即可了。5个怪状态压缩着推断,由于这个怪在第二次经过的时候已经死了,不用花费时间去杀死它

#include <map>
#include <queue>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int maxn=110;
int sx,sy,ex,ey,n,m,cnt;
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int vis[maxn][maxn][10][40];
char str[maxn][maxn];
struct edge{
int x,y,step,numkey,ss;
};
struct snake{
int x,y;
}sna[10];
int bfs(){
queue<edge>que;
edge c,ne;
memset(vis,0,sizeof(vis));
c.x=sx,c.y=sy,c.step=0,c.numkey=0,c.ss=0;
vis[c.x][c.y][0][0]=1;
que.push(c);
int ans=inf;
while(!que.empty()){
c=que.front();que.pop();
if(c.x==ex&&c.y==ey&&c.numkey==m){
ans=min(ans,c.step);
}
for(int i=0;i<4;i++){
int xx=dir[i][0]+c.x;
int yy=dir[i][1]+c.y;
if(xx<0||xx>n-1||yy<0||yy>n-1||str[xx][yy]=='#') continue;
if(vis[xx][yy][c.numkey][c.ss]) continue;
ne.x=xx;ne.y=yy;ne.step=c.step+1;ne.numkey=c.numkey;ne.ss=c.ss;
if(str[xx][yy]>='1'&&str[xx][yy]<='9'){//假设走到的是钥匙的位置进行推断
int t=str[xx][yy]-'0';
if(ne.numkey==t-1){//钥匙刚好是当前钥匙数+1,就符合条件
ne.numkey++;
vis[ne.x][ne.y][ne.numkey][ne.ss]=1;
que.push(ne);
}else{//不符合直接压进队列
vis[ne.x][ne.y][ne.numkey][ne.ss]=1;
que.push(ne);
}
}else if(str[xx][yy]=='S'){//遇到怪进行推断
for(int i=0;i<cnt;i++){
if(xx==sna[i].x&&yy==sna[i].y){
if((ne.ss>>i)&1){//说明这个怪已经死掉了
vis[ne.x][ne.y][ne.numkey][ne.ss]=1;
que.push(ne);
}else{//没有死掉的话时间+1,状态更新
ne.step++;
ne.ss+=(1<<i);
vis[ne.x][ne.y][ne.numkey][ne.ss]=1;
que.push(ne);
}
break;
}
}
}else{
vis[ne.x][ne.y][ne.numkey][ne.ss]=1;
que.push(ne);
}
}
}
return ans;
}
int main(){
while(scanf("%d%d",&n,&m)!=-1){
if(n==0&&m==0) break;
cnt=0;
for(int i=0;i<n;i++) scanf("%s",str[i]);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(str[i][j]=='K')sx=i,sy=j;
if(str[i][j]=='T')ex=i,ey=j;
if(str[i][j]=='S'){
sna[cnt].x=i,
sna[cnt++].y=j;//记录怪的位置和数量
}
}
}
int ans=bfs();
if(ans==inf) puts("impossible");
else printf("%d\n",ans);
}
return 0;
}

最新文章

  1. shell及脚本3——正则表达式
  2. JAVA 多线程随笔 (一) 可见性和volatile关键字
  3. nodejs——网络编程模块
  4. 【读书笔记】iOS-Tagged Pointer对象-注意事项
  5. 使用phpmyadmin导入SQL数据报错:#1062 - Duplicate entry &#39;...
  6. c++学习-虚函数
  7. Redrain仿酷狗音乐播放器开发完毕,发布测试程序
  8. cf Round 601
  9. 打开U盘里是U盘的快捷方式?(2013.12.05)
  10. Excel表无法正常打开
  11. 使用dojo的tree
  12. 干I​n​l​a​y​的​生​产​过​程​
  13. 基于visual Studio2013解决面试题之0208二叉搜索树后序遍历序列
  14. js判断ip地址,子网掩码,网关的逻辑性检查
  15. Kafka 源代码分析之LogManager
  16. vue设置默认地址和配送方式
  17. 简单的图像显著性区域特征提取方法-----opencv实现LC,AC,FT
  18. Oracle PGA
  19. SharpGL学习笔记(五) 视口变换
  20. Hadoop专业解决方案-第13章 Hadoop的发展趋势

热门文章

  1. 浅谈三款常用软件 - Chrome、Intellij IDEA、Cygwin
  2. Django+Nginx+uwsgi搭建自己的博客(八)
  3. Hibernate 基于外键的双向一对一关联映射
  4. 【BZOJ 3238】 3238: [Ahoi2013]差异(SAM)
  5. 《时间序列分析——基于R》王燕,读书笔记
  6. noip2013 车站分级
  7. Qt on android 蓝牙开发(控制小车)
  8. mysql存储过程导入表
  9. 如何测试Nginx的高性能
  10. [Asp.net]使用flexpaper+swftools大文件分页转换实现在线预览