HDU 5025Saving Tang Monk BFS + 二进制枚举状态
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 + 二进制枚举状态的更多相关文章
- 【uva 1151】Buy or Build(图论--最小生成树+二进制枚举状态)
题意:平面上有N个点(1≤N≤1000),若要新建边,费用是2点的欧几里德距离的平方.另外还有Q个套餐,每个套餐里的点互相联通,总费用为Ci.问让所有N个点连通的最小费用.(2组数据的输出之间要求有换 ...
- HDU 5025 Saving Tang Monk --BFS
题意:给一个地图,孙悟空(K)救唐僧(T),地图中'S'表示蛇,第一次到这要杀死蛇(蛇最多5条),多花费一分钟,'1'~'m'表示m个钥匙(m<=9),孙悟空要依次拿到这m个钥匙,然后才能去救唐 ...
- HDU 5094 --Maze【BFS && 状态压缩】
Maze Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Others) Total Sub ...
- 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 ...
- [ACM] HDU 5025 Saving Tang Monk (状态压缩,BFS)
Saving Tang Monk Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) ...
- hdu 5025 Saving Tang Monk(bfs+状态压缩)
Description <Journey to the West>(also <Monkey>) is one of the Four Great Classical Nove ...
- HDU 5025:Saving Tang Monk(BFS + 状压)
http://acm.hdu.edu.cn/showproblem.php?pid=5025 Saving Tang Monk Problem Description <Journey to ...
- hdu 5025 Saving Tang Monk 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092939.html 题目链接:hdu 5025 Saving Tang Monk 状态压缩 ...
- ACM学习历程—HDU 5025 Saving Tang Monk(广州赛区网赛)(bfs)
Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classi ...
随机推荐
- [LeetCode]题解(python):135-Candy
题目来源: https://leetcode.com/problems/candy/ 题意分析: 有N个孩子站成一条线.每个孩子有个排名.要求1.每个孩子至少一个糖果,2.相邻的孩子,那么较高排名的孩 ...
- [转]使用storyboard实现页面跳转,简单的数据传递
由于最近才接触到IOS,苹果已经建议storyboard来搭建所有界面了,于是我也追随时尚,直接开始使用storyboard.(不料在涉及到页面跳转的时候,遇到的问题是:点击后没有任何反应)众所周知, ...
- Grunt.js 上手
Official Site gruntjs.org/docs/getting-started.html 或者看http://tgideas.qq.com/webplat/info/news_versi ...
- 浅谈USB设备的VID和PID
根据USB规范的规定,所有的USB设备都有供应商ID(VID)和产品识别码(PID),主机通过不同的VID和PID来区别不同的设备,VID和PID都是两个字节长,其中,供应商ID(VID)由供应商向U ...
- Scraping JavaScript webpages with webkit | WebScraping.com
Scraping JavaScript webpages with webkit | WebScraping.com Scraping JavaScript webpages with webkit ...
- codeforces#FF DIV2C题DZY Loves Sequences(DP)
题目地址:http://codeforces.com/contest/447/problem/C C. DZY Loves Sequences time limit per test 1 second ...
- poj1144 Network【tarjan求割点】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4319585.html ---by 墨染之樱花 [题目链接]http://poj.org/p ...
- epoll相关
1) 能不能给一个使用epoll相关API进行IO监控的示例?在<<epoll学习笔记>>中有一个简单的示例说明epoll相关API的使用, 但是这个示例是非常简单的, 它仅仅 ...
- Ext JS学习第十三天 Ext基础之 Ext.Element
•Ext.Element提供了181个方法,嗯,还没完,只是在4.1版本中是这样,最新的4.2版本貌似又增加了新方法,可谓是相当丰富给力.那么根据操作类型基本可以分为查询系.DOM操作系.样式操作系. ...
- SharePoint需要开启的网站集功能
1. 管理网站功能 2. 网站集功能