转载自:http://blog.csdn.net/madaidao/article/details/42616743
Bob was playing MC and was punished by Alice. Bob was trapped in a maze and there were some characters on some specific cells. When he walks on a specific point, he will pick up the character automatically (he cannot refuse to do that) and push back the character in his bag (You can treat it as adding a character to the end of a string and initially, the string is empty.). Alice has set several goal strings and when Bob's bag contains any one of the strings, Bob is enabled to return to the true world.
Bob can walk to the adjacent cell (up, down, left, right) at one time, and it costs no time to pick up the character and the character won't disappear, which means if Bob want's he can get endless characters once he walked on the certain cell but he must pick up at least one character.
Bob wants to leave the maze as soon as possible, and he asks you for the shortest time that he can go out of that maze.
Input
The first line is an integer n, indicating the number of testcases.
In each case, the first line is two integers L and C (0 < L, C ≤ 20). After this, L lines follow, and each has Ccharacters. For each character, '.' stands for an open space, '#' stands for a wall which cannot be crossed, '@' stands for the beginning point of the maze. All capital letters 'A' to 'Z' stand for the characters which can be picked up.
After that, there is one integer W, which means the number of goal strings (0 < W ≤ 200). And W lines following, each line has a string, containing letters 'A' to 'Z' only, which length is less than 100.
Output
For each case, you should output an integer. The answer is the minimum time that Bob must use to get out of the maze. If he can't do that, you should output -1.
Sample Input
2 5 5 A.DB# @#.## .#..C .#... ..... 3 AB AC BC 5 5 A.DB# @#.## .#..C .#... ..... 2 AADBBBDCC AC
Sample Output
11 9
题意:BOb在一个L*C的格子迷宫中,有些特别的格子里面有一个大写字母,每次Bob走到这个格子,至少要添加一个该字母到包里,相当于添加一个字母到字符串的末尾,初始的时候字符串为空。可以添加无数个(字母拿了不会消失,拿字母不花时间)。Alice有一些字符串,若有一个字符串为Bob包里的串的子串,Bob就可以走出迷宫。求Bpb走出迷宫的最小时间。
题解:枚举Alice的串,求出靠每个Alice的串走出迷宫的最小时间。对于每个串s,我们用dp[i][j][k] 表示当前在点(i,j),背包里的串的长度为j的后缀和s的长度为k的前缀相同,走到该状态的最短时间。用spfa的方法转移即可。代码如下:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string.h> #include<string> #include<queue> #include<stack> #include<map> #include<set> #include<stdlib.h> #include<vector> #define inff 0x3fffffff #define nn 110000 #define mod 1000000007 typedef long long LL; const LL inf64=inff*(LL)inff; using namespace std; int c,l; int w; int dir[4][2]={1,0,-1,0,0,1,0,-1}; char tu[50][50]; LL dp[50][50][1100]; bool inque[50][50][1100]; struct node { int x,y,zt; node(){} node(int xx,int yy,int zzt) { x=xx,y=yy,zt=zzt; } }sta,tem; queue<node>que; void gengxin(int x,int y,int zt,int val) { if(dp[sta.x][sta.y][sta.zt]+val<dp[x][y][zt]) { dp[x][y][zt]=dp[sta.x][sta.y][sta.zt]+val; if(!inque[x][y][zt]) { inque[x][y][zt]=true; que.push(node(x,y,zt)); } } } LL solve(string s) { int ls=s.size(); int i,j,k; for(i=0;i<c;i++) { for(j=0;j<l;j++) { for(k=0;k<=ls;k++) { inque[i][j][k]=false; dp[i][j][k]=inf64; } } } while(que.size()) que.pop(); for(i=0;i<c;i++) { for(j=0;j<l;j++) { if(tu[i][j]=='@') { dp[i][j][0]=0; inque[i][j][0]=true; que.push(node(i,j,0)); } } } int x,y; LL re=inf64; while(que.size()) { sta=que.front(); que.pop(); inque[sta.x][sta.y][sta.zt]=false; if(sta.zt==ls) { re=min(re,dp[sta.x][sta.y][sta.zt]); continue; } if(tu[sta.x][sta.y]==s[sta.zt]) { gengxin(sta.x,sta.y,sta.zt+1,0); } for(i=0;i<4;i++) { x=sta.x+dir[i][0]; y=sta.y+dir[i][1]; if(x>=0&&x<c&&y>=0&&y<l) { if(tu[x][y]==s[sta.zt]) { gengxin(x,y,sta.zt+1,1); } if(tu[x][y]=='@'||tu[x][y]=='.') { gengxin(x,y,sta.zt,1); } if(tu[x][y]>='A'&&tu[x][y]<='Z'&&tu[x][y]!=s[sta.zt]) { gengxin(x,y,0,1); } } } } return re; } char sr[1100]; int main() { int t,i; string s; scanf("%d",&t); while(t--) { scanf("%d%d",&c,&l); for(i=0;i<c;i++) { scanf("%s",tu[i]); } scanf("%d",&w); getchar(); LL ans=inf64; for(i=1;i<=w;i++) { gets(sr); s=sr; ans=min(ans,solve(s)); } if(ans==inf64) printf("%d ",-1); else printf("%lld ",ans); } return 0; }