百练 4116 拯救行动(bfs)
2016-12-04 02:01
330 查看
描述
输入
第一行为一个整数S,表示输入的数据的组数(多组输入)
随后有S组数据,每组数据按如下格式输入
1、两个整数代表N和M, (N, M <= 200).
2、随后N行,每行有M个字符。”@”代表道路,”a”代表公主,”r”代表骑士,”x”代表守卫, “#”代表墙壁。
输出
如果拯救行动成功,输出一个整数,表示行动的最短时间。
如果不可能成功,输出”Impossible”
样例输入
样例输出
思路
这道题用普通bfs可以过样例,但是提交过不了,这道题是看了别人代码做的,
有两种方法.
一种是用priority_queue 做(暂时不太懂)
另一种方法是拆点
拆点就是对于 ‘x’ ,它的扩展要分两次:
对于(‘x’,0) ,它只能扩展出 ( ‘x’ , 1 )
对于(‘x’,1) , 它可以往四个方向扩展.
第一种 priority_queue
第二种 拆点
公主被恶人抓走,被关押在牢房的某个地方。牢房用N*M (N, M <= 200)的矩阵来表示。矩阵中的每项可以代表道路(@)、墙壁(#)、和守卫(x)。 英勇的骑士(r)决定孤身一人去拯救公主(a)。我们假设拯救成功的表示是“骑士到达了公主所在的位置”。由于在通往公主所在位置的道路中可能遇到守卫,骑士一旦遇到守卫,必须杀死守卫才能继续前进。 现假设骑士可以向上、下、左、右四个方向移动,每移动一个位置需要1个单位时间,杀死一个守卫需要花费额外的1个单位时间。同时假设骑士足够强壮,有能力杀死所有的守卫。 给定牢房矩阵,公主、骑士和守卫在矩阵中的位置,请你计算拯救行动成功需要花费最短时间。
输入
第一行为一个整数S,表示输入的数据的组数(多组输入)
随后有S组数据,每组数据按如下格式输入
1、两个整数代表N和M, (N, M <= 200).
2、随后N行,每行有M个字符。”@”代表道路,”a”代表公主,”r”代表骑士,”x”代表守卫, “#”代表墙壁。
输出
如果拯救行动成功,输出一个整数,表示行动的最短时间。
如果不可能成功,输出”Impossible”
样例输入
2 7 8 #@#####@ #@a#@@r@ #@@#x@@@ @@#@@#@# #@@@##@@ @#@@@@@@ @@@@@@@@ 13 40 @x@@##x@#x@x#xxxx##@#x@x@@#x#@#x#@@x@#@x xx###x@x#@@##xx@@@#@x@@#x@xxx@@#x@#x@@x@ #@x#@x#x#@@##@@x#@xx#xxx@@x##@@@#@x@@x@x @##x@@@x#xx#@@#xxxx#@@x@x@#@x@@@x@#@#x@# @#xxxxx##@@x##x@xxx@@#x@x####@@@x#x##@#@ #xxx#@#x##xxxx@@#xx@@@x@xxx#@#xxx@x##### #x@xxxx#@x@@@@##@x#xx#xxx@#xx#@#####x#@x xx##@#@x##x##x#@x#@a#xx@##@#@##xx@#@@x@x x#x#@x@#x#@##@xrx@x#xxxx@##x##xx#@#x@xx@ #x@@#@###x##x@x#@@#@@x@x@@xx@@@@##@@x@@x x#xx@x###@xxx#@#x#@@###@#@##@x#@x@#@@#@@ #@#x@x#x#x###@x@@xxx####x@x##@x####xx#@x #x#@x#x######@@#x@#xxxx#xx@@@#xx#x#####@
样例输出
13 7
思路
这道题用普通bfs可以过样例,但是提交过不了,这道题是看了别人代码做的,
有两种方法.
一种是用priority_queue 做(暂时不太懂)
另一种方法是拆点
拆点就是对于 ‘x’ ,它的扩展要分两次:
对于(‘x’,0) ,它只能扩展出 ( ‘x’ , 1 )
对于(‘x’,1) , 它可以往四个方向扩展.
第一种 priority_queue
/************************************************************************* > File Name: bl4116.cpp > Author:ukiy > Mail: > Created Time: 2016年12月03日 星期六 22时34分06秒 ************************************************************************/ #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstdlib> #include<climits> #include<string> #include<cstring> #include<vector> #include<set> #include<list> #include<map> #include<queue> int dire[4][2]={ {0,1},{1,0},{0,-1},{-1,0} }; int dire2[8][2]={{-1,-1},{-1,0},{-1,1},{ 0,-1},{ 0,1},{ 1,-1},{ 1,0},{ 1,1}}; #define rep(i,a,b) for(int i=(a);i<=(b);(i++)) #define inf 0x3f3f3f #define ll long long #define pi acos(-1) int dire3[6][3]={ {0,0,1},{0,1,0},{1,0,0},{0,0,-1},{0,-1,0},{-1,0,0} }; using namespace std; const int maxn=205; int visit[maxn][maxn]; char a[maxn][maxn]; int n,m; int sx,sy,dx,dy; struct node{ int x,y,step; bool operator < (const node& p) const { return step>p.step; } node(int xx,int yy,int s):x(xx),y(yy),step(s){}; }; int bfs(int x,int y){ priority_queue<node> q; q.push(node(x,y,0)); visit[x][y]=1; while(!q.empty()){ int hx=q.top().x,hy=q.top().y,hs=q.top().step;q.pop(); if(hx==dx && hy==dy) return hs; rep(i,0,3){ int tx=hx+dire[i][0]; int ty=hy+dire[i][1]; if(tx<0||tx>=n||ty<0||ty>=m||a[tx][ty]=='#'||visit[tx][ty]) continue; if(a[tx][ty]=='x') q.push(node(tx,ty,hs+2)); else q.push(node(tx,ty,hs+1)); visit[tx][ty]=1; } } return -1; } /* int bfs(){ int front=0; int rear=1; q[front].x=sx,q[front].y=sy,q[front].step=0; visit[sx][sy]=1; int flag=0; while(front < rear){ if(q[front].x==dx && q[front].y==dy) return q[front].step; rep(i,0,3){ int px=q[front].x+dire[i][0]; int py=q[front].y+dire[i][1]; if(px<0||px>=n||py<0||py>=m||visit[px][py]||a[px][py]=='#') continue; else{ q[rear].x=px; q[rear].y=py; if(a[px][py]=='@'||a[px][py]=='a') q[rear].step=q[front].step+1; else if(a[px][py]=='x') q[rear].step=q[front].step+2; visit[px][py]=1; rear++; } } front++; } return -1; } */ int main() { std::ios::sync_with_stdio(false); #ifndef OnlineJudge //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int t; cin>>t; while(t--){ cin>>n>>m; rep(i,0,n-1){ rep(j,0,m-1){ cin>>a[i][j]; if(a[i][j]=='r') sx=i,sy=j; if(a[i][j]=='a') dx=i,dy=j; } } memset(visit,0,sizeof(visit)); int ans=bfs(sx,sy); if(ans==-1) printf("Impossible\n"); else printf("%d\n",ans); } return 0; }
第二种 拆点
/************************************************************************* > File Name: bl4116_2.cpp > Author:ukiy > Mail: > Created Time: 2016年12月04日 星期日 01时19分50秒 ************************************************************************/ #include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstdlib> #include<climits> #include<string> #include<cstring> #include<vector> #include<set> #include<list> #include<map> #include<queue> int dire[4][2]={ {0,1},{1,0},{0,-1},{-1,0} }; int dire2[8][2]={{-1,-1},{-1,0},{-1,1},{ 0,-1},{ 0,1},{ 1,-1},{ 1,0},{ 1,1}}; #define rep(i,a,b) for(int i=(a);i<=(b);(i++)) #define inf 0x3f3f3f #define ll long long #define pi acos(-1) int dire3[6][3]={ {0,0,1},{0,1,0},{1,0,0},{0,0,-1},{0,-1,0},{-1,0,0} }; using namespace std; #define maxn 205 struct node{ int r,c,t; node (int r,int c,int t):r(r),c(c),t(t){} }; char g[maxn][maxn]; int G[maxn][maxn]; int vis[maxn][maxn]; int sx,sy,dx,dy; int n,m; int bfs(){ int ans=inf; queue<node> q; q.push(node(sx,sy,0)); while(!q.empty()){ node p = q.front(); if(g[p.r][p.c]=='a'){ ans=min(ans,p.t); q.pop(); break; } if(g[p.r][p.c]=='x'&&G[p.r][p.c]==1){ //第二次拆点 q.push(node(p.r,p.c,p.t+1)); G[p.r][p.c]=0; } else{ rep(i,0,3){ int tr=p.r+dire[i][0]; int tc=p.c+dire[i][1]; if(tr>=0&&tr<n&&tc>=0&&tc<m && G[tc]){ if(g [tc]!='x'){ q.push(node(tr,tc,p.t+1)); G [tc]=0; } if(g [tc]=='x'&&G [tc]==2){//第一次拆点 q.push(node(tr,tc,p.t+1)); G [tc]=1; } } } } q.pop(); } if(ans==inf) return -1; else return ans; } int main() { std::ios::sync_with_stdio(false); #ifndef OnlineJudge //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); #endif int T; cin>>T; while(T--){ cin>>n>>m; rep(i,0,n-1){ rep(j,0,m-1){ cin>>g[i][j]; if(g[i][j]=='x') G[i][j]=2; else if(g[i][j]=='@'||g[i][j]=='a') G[i][j]=1; else if(g[i][j]=='r') G[i][j]=0,sx=i,sy=j; else G[i][j]=0; } } //memset(G,0,sizeof(G)); int ans=bfs(); if(ans==-1) printf("Impossible\n"); else printf("%d\n",ans); } return 0; }
priority_queue 原文
BRCOCOLI http://blog.csdn.net/qq_34446253/article/details/51986930
拆点 原文
appledaily http://blog.csdn.net/hhhhhhj123/article/details/47070659相关文章推荐
- openjudge 4116:拯救行动
- 百练 4116 拯救行动
- poj 4980 拯救行动(变式bfs)
- 百练4116:拯救行动解题报告
- 百练 4116 拯救行动
- 百练4980 拯救行动[BFS]
- 百练4980--拯救行动(BFS)
- 拯救行动(变种bfs)
- Openjudge4980 拯救行动(bfs)
- |Tyvj|BFS|P1117 拯救ice-cream
- PTA - 拯救007 ( BFS )
- 程设模拟考 G:拯救行动
- BFS 搜索 Problem 1012 Rescue 拯救天使
- dfs 拯救行动
- 2843 拯救炜哥 (bfs)
- Win7实用技巧之四拯救桌面行动之Jumplist
- 百练 4116 拯救行动 【bfs的内涵理解】
- HDOJ1242 拯救天使 (BFS)
- 【openjudge】拯救行动
- openjudge 拯救行动