本文主要是介绍HDU 1983 Kaitou Kid - The Phantom Thief (2),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
转自:http://blog.csdn.net/madrishing/article/details/7874207?locationNum=6
'S':入口
'E':出口
'J':放有宝石的区域,至少出现一次
'.':空白区域
'#':墙
2 5 5 5 SJJJJ ..##J .JJJJ .J... EJ... 5 5 6 SJJJJ ..##J .JJJJ .J... EJ...
0 2
方法:DFS+BFS.题目要求问最少堵多少个点让他不能完成任务.因为 地图只有 8*8 ,并且最多只需要堵 4个地方(起点或者终点的四个方向),所以直接暴力枚举0~3个点的堵法,都不能堵的话,就输出4.枚举用DFS搞定。
#include<queue>
#include<iostream>
#include<algorithm>
#define FOR(i,n) for(i=0;i<n;i++) using namespace std; char Map[2][10][10];//地图
char vis[2][10][10];//访问记录
int sx,sy,n,m,t;
int dir[][2]={{1,0},{-1,0},{0,1},{0,-1}};//下,上,右,左 struct Node{ int x,y,f;//坐标,楼层
}; bool bfs(){//标准的BFS queue<Node>que; Node no,ne; int i; memset(vis,-1,sizeof(vis)); no.x=sx,no.y=sy,no.f=0; que.push(no); vis[0][sx][sy]=0; while(!que.empty()){ no=que.front(),que.pop(); if(vis[no.f][no.x][no.y]>=t) continue;//算是剪枝吧 FOR(i,4){ ne.x=no.x+dir[i][0],ne.y=no.y+dir[i][1],ne.f=no.f; if(ne.x<0||ne.y<0||ne.x>=n||ne.y>=m) continue; if(Map[ne.f][ne.x][ne.y]=='#') continue; if(Map[ne.f][ne.x][ne.y]=='J') ne.f=1; if(Map[ne.f][ne.x][ne.y]=='E'&&ne.f) return false;//ne.f=1表示已经拿到J if(vis[ne.f][ne.x][ne.y]!=-1) continue; vis[ne.f][ne.x][ne.y]=vis[no.f][no.x][no.y]+1; que.push(ne); } } return true;
} bool DFS(int tot){//标准DFS ,tot表示要堵的点的个数 int i,j; if(!tot) return bfs(); FOR(i,n) FOR(j,m){ if(Map[0][i][j]=='.'||Map[0][i][j]=='J'){ char emp=Map[0][i][j]; Map[0][i][j]='#'; if(DFS(tot-1)) return true; Map[0][i][j]=emp; } } return false;
} int main(){ int k,i,j,a,b; scanf("%d",&k); while(k--){ scanf("%d%d%d",&n,&m,&t); FOR(i,n){ scanf("%s",Map[0][i]); FOR(j,m) if(Map[0][i][j]=='S') sx=i,sy=j; strcpy(Map[1][i],Map[0][i]);//复制第二层楼 } FOR(i,4) if(DFS(i)){//把0~3个的点搜索一遍 printf("%d\n",i); break; } i==4?puts("4"):0;//如果前三点都没有成立的,最多四个,所以输出四 } return 0;
}
这篇关于HDU 1983 Kaitou Kid - The Phantom Thief (2)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!