HDU 5025Saving Tang Monk BFS + 二进制枚举状态

时间:2021-03-20 23:52:23

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(图论--最小生成树&plus;二进制枚举状态)

    题意:平面上有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&semi;amp&semi;&amp&semi;amp&semi; 状态压缩】

    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. &lbrack;ACM&rsqb; 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&plus;状态压缩)

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

  7. HDU 5025:Saving Tang Monk(BFS &plus; 状压)

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

  8. hdu 5025 Saving Tang Monk 状态压缩dp&plus;广搜

    作者: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. 非对称技术栈实现AES加密解密

    非对称技术栈实现AES加密解密 正如前面的一篇文章所述,https协议的SSL层是实现在传输层之上,应用层之下,也就是说在应用层上看到的请求还是明码的,对于某些场景下要求这些http请求参数是非可读的 ...

  2. PHP 字符串左边补0,字符串右边补0

    概述:项目中经常会使用到在一串编码左边.右边甚至中间自动填充制定字符如"0" 并且制定填充后的字符串长度. 函数str_pad:该函数返回 input 被从左端.右端或者同时两端被 ...

  3. 配置spring事务管理的几种方式&lpar;声明式事务&rpar;

    Spring配置文件中关于事务配置总是由三个组成部分,分别是DataSource.TransactionManager和代理机制这三部分,无论哪种配置方式,一般变化的只是代理机制这部分. DataSo ...

  4. 发布mvc3的项目时system&period;web&period;mvc 版本 为3&period;0&period;0&period;1高于服务器版本3&period;0&period;0&period;0 升级到3&period;0&period;0&period;1

    下载地址在这里: http://www.microsoft.com/zh-cn/download/details.aspx?id=44533&WT.mc_id=rss_alldownloads ...

  5. Ext&period;form&period;FormPanel定义的参数说明

    1.formId : String (可选的)FORM标签的id(默认是自动生成的). 2.labelWidth : Number 标签的宽度.该属性级联于子容器. 3. itemCls : Stri ...

  6. su 和 sudo 命令的区别-转载

    link 一. 使用 su 命令临时切换用户身份                   1.su 的适用条件和威力   su命令就是切换用户的工具,怎么理解呢?比如我们以普通用户beinan登录的,但要 ...

  7. java字符流

    网上有很多地方说inputStreamReader和outStreamWriter.BufferedReader和BufferedWriter都是字符流.不过也有地方说inputStreamReade ...

  8. SpringCloud实战8-Bus消息总线

    好了现在我们接着上一篇的随笔,继续来讲.上一篇我们讲到,我们如果要去更新所有微服务的配置,在不重启的情况下去更新配置,只能依靠spring cloud config了,但是,是我们要一个服务一个服务的 ...

  9. Linux&lpar;CentOS7&rpar;下如何配置多个JDK环境变量

    一.Linux版本 二.复制粘贴多个JDK出来,如下 cp -R jdk1.7.0_80/ jdk1.7.0_80-2 cp -R jdk1.7.0_80/ jdk1.7.0_80-3 三.配置多个J ...

  10. 可变参数函数&lpar;stdarg&period;h&rpar;的使用

    2013/5/3记录: stdarg.h是C语言中C标准函数库的头文件,stdarg是由standard(标准) arguments(参数)简化而来,主要目的为让函数能够接收可变参数.   stdar ...