3A的题目,第一次TLE,是因为一次BFS起点到终点状态太多爆掉了时间。

第二次WA,是因为没有枚举蛇的状态。

解体思路:

因为蛇的数目是小于5只的,那就首先枚举是否杀死每只蛇即可。

然后多次BFS,先从起点到第一把钥匙,不能往回走,要用VIS数组标记。

第二次从第一把钥匙走到第二把钥匙。

最后一次从最后一把钥匙走到终点即可。

Tips 1: 在每次BFS过程中使用优先队列保证每次是最小步长的状态。

Tips2 :使用二进制枚举蛇的状态

Tips3:首先使用DFS判断是否绝对有解,如果无解输出"impossible",如果有解则继续。

Tips4:多次 BFS,而不是一次BFS,否则会导致状态太多TLE

代码如下:

 //#pragma comment(linker, "/STACK:16777216") //for c++ Compiler
#include <stdio.h>
#include <iostream>
#include <cstring>
#include <cmath>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#define ll long long
#define Max(a,b) (((a) > (b)) ? (a) : (b))
#define Min(a,b) (((a) < (b)) ? (a) : (b))
#define Abs(x) (((x) > 0) ? (x) : (-(x)))
using namespace std; const int INF = 0x3f3f3f3f;
const int MAXN = ;
const double eps = 1e-; struct node{
int x,y,step;
}; char map[][];
int vis[][];
int to[][]= {,,-,,,,,-};
int n,m,sx,sy,ex,ey,ans; bool operator < (node a, node b){
return a.step > b.step;
} int check(int x,int y){
if(x< || x>=n || y< || y>=n)
return ;
if(map[x][y]=='#' || vis[x][y])
return ;
return ;
} void bfs(int sx, int sy, int k){
int i;
priority_queue <node> Q;
node a,next;
a.x = sx;
a.y = sy;
a.step = ;
vis[a.x][a.y]=;
Q.push(a);
while(!Q.empty()){
a = Q.top();
//printf("x = %d y = %d step = %d\n",a.x,a.y,a.step);
Q.pop();
if(k <= m){
if(map[a.x][a.y] == k + ''){
ans += a.step;
ex = a.x;
ey = a.y;
//printf("%d %d cur _ ans = %d\n",ex, ey,ans);
return;
}
} else{
if(map[a.x][a.y] == 'T'){
ans += a.step;
ex = a.x;
ey = a.y;
//printf("%d %d cur _ ans = %d\n",ex, ey,ans);
return;
}
}
for(i = ; i<; i++){
next = a;
next.x+=to[i][];
next.y+=to[i][];
if(check(next.x,next.y)) continue;
next.step=a.step+;
if(map[a.x][a.y] == 'S'){
++next.step;
}
vis[next.x][next.y] = ;
Q.push(next);
}
if(map[a.x][a.y] == 'S'){
map[a.x][a.y] = '.';
}
}
ans =INF;
return ;
} void dfs(int x, int y){
for(int i = ; i<; i++){
int _x = x + to[i][];
int _y = y + to[i][];
if(check(_x,_y)) continue;
if(map[_x][_y] != '#'){
vis[_x][_y] = ;
dfs(_x,_y);
}
}
}
int main(){
int i,j,cc,s_flag;
while(EOF != scanf("%d%d",&n,&m)){
if(n == && m == ) break;
s_flag = ;
node S[];
for(i = ; i<n; i++)
scanf("%s",map[i]);
for(i = ; i<n; i++){
for(j = ; j<n; j++){
if(map[i][j]=='K'){
sx = i;
sy = j;
}else if(map[i][j] == 'T'){
ex = i,ey = j;
}else if(map[i][j] == 'S'){
S[s_flag].x = i, S[s_flag++].y = j;
}
}
}
memset(vis,,sizeof(vis));
vis[sx][sy] = ;
dfs(sx,sy);
int kkk[];
bool flag = false;
memset(kkk, , sizeof(kkk));
for(i = ; i < n; ++i){
for(j = ; j < n; ++j){
if(map[i][j] >= '' && map[i][j] <= '' && vis[i][j]){
kkk[map[i][j] - ''] = ;
}
}
}
for(i = ; i <= m; ++i){
if(!kkk[i]) break;
}
if(i == m + ) flag = true; if(vis[ex][ey] == || !flag){
printf("impossible\n");
continue;
}
s_flag = ;
for(i = ; i<n; i++){
for(j = ; j<n; j++){
if(map[i][j] == 'S'){
S[s_flag].x = i, S[s_flag++].y = j;
}
}
}
int minans=INF;
for(cc = ; cc < ( << s_flag); ++cc){
ans = ;
for(i = ; i <s_flag; ++i){
if(( << i) & cc){
map[S[i].x][S[i].y] = '.';
ans++;
}
else {
map[S[i].x][S[i].y] = '#';
}
}
for(i = ; i < n; ++i){
for(j = ; j < n; ++j){
if(map[i][j] == 'K'){
ex = i;
ey = j;
}
}
}
for(int k = ; k <= m + ; ++k){
memset(vis, , sizeof(vis));
sx = ex;
sy = ey;
bfs(sx, sy, k);
}
minans=min(minans,ans);
}
printf("%d\n",minans);
}
return ;
}

HDU 5025Saving Tang Monk BFS + 二进制枚举状态的更多相关文章

  1. 【uva 1151】Buy or Build(图论--最小生成树+二进制枚举状态)

    题意:平面上有N个点(1≤N≤1000),若要新建边,费用是2点的欧几里德距离的平方.另外还有Q个套餐,每个套餐里的点互相联通,总费用为Ci.问让所有N个点连通的最小费用.(2组数据的输出之间要求有换 ...

  2. HDU 5025 Saving Tang Monk --BFS

    题意:给一个地图,孙悟空(K)救唐僧(T),地图中'S'表示蛇,第一次到这要杀死蛇(蛇最多5条),多花费一分钟,'1'~'m'表示m个钥匙(m<=9),孙悟空要依次拿到这m个钥匙,然后才能去救唐 ...

  3. HDU 5094 --Maze【BFS &amp;&amp; 状态压缩】

    Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Sub ...

  4. HDU 5025 Saving Tang Monk 【状态压缩BFS】

    任意门:http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Time Limit: 2000/1000 MS (Java/O ...

  5. [ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)

    Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  6. hdu 5025 Saving Tang Monk(bfs+状态压缩)

    Description <Journey to the West>(also <Monkey>) is one of the Four Great Classical Nove ...

  7. HDU 5025:Saving Tang Monk(BFS + 状压)

    http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Problem Description   <Journey to ...

  8. hdu 5025 Saving Tang Monk 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...

  9. ACM学习历程—HDU 5025 Saving Tang Monk(广州赛区网赛)(bfs)

    Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classi ...

随机推荐

  1. 韦根(Wiegand)数据传输格式

    韦根数据传输使用TTL电平,有两条数据线,分别称为DATA0和DATA1.无数据传输时,两条线都是高电平,当传输“1”时,DATA0为高,DATA1为低:当传输“0”时,DATA0为低,DATA1为高 ...

  2. Android---intent传递putStringArrayListExtra

    Intent是Activity与Activity之间,Activity与Service之间传递参数的介质,使用Intent和Bundle在组件之间传递数据,而这两种通常实现的是Java基本对象类型和S ...

  3. $.getJSON(url,function success(){})回调函数不起作用

    有个问题好久没有解决,就是: $.getJSON(url,function success(){}) 其中的回调函数,总也不执行. 以前也做过,但那都是CTRL+C,CTRL+V,也没有细想. 目标就 ...

  4. c#与.NET的区别

    C#与.NET的关系 C# 可以通过.NET平台来编写 部署 运行.NET应用程序VB.NET.......NET语言 C#是专门为.NET平台而生的(面向对象) .NET平台的重要组成:1.FCL- ...

  5. C#中泛型、程序集一些基本运用(Fifteenth Day)

    今天主要在学习了泛型和程序集以及一些细碎的知识的运用.下面我就把今天所学的总结一下. 理论: 泛型: * 英文名字是Generic,可以让多个类型共享一组代码,泛型允许我们声明类型参数化,可以用不同的 ...

  6. iOS开发之第三方登录微博-- 史上最全最新第三方登录微博方式实现

    相关资源地址: 本项目demo地址 :  https://github.com/zhonggaorong/weiboSDKDemo 最新SDK下载:  最新微博SDK 官网注册地址:点击打开链接 最新 ...

  7. javascript对象属性——数据属性和访问器属性

    ECMA-262第五版在定义时,描述了属性property的各种特征,定义这些特性是为了实现javascript引擎用的,为了表示该特性是内部值,规范把它们放在了两对儿方括号中,例如[[Enumera ...

  8. BZOJ 1652: [Usaco2006 Feb]Treats for the Cows( dp )

    dp( L , R ) = max( dp( L + 1 , R ) + V_L * ( n - R + L ) , dp( L , R - 1 ) + V_R * ( n - R + L ) ) 边 ...

  9. js实现input输入框只能输入数字的功能

    <input type="text" style="ime-mode:disabled;" onpaste="return false;&quo ...

  10. Qt之QNetworkInterface(查询网络接口),QHostInfo(查询主机IP)

    http://blog.csdn.net/u011012932/article/details/50775052 http://blog.csdn.net/u011012932/article/det ...