状态的正确选取,图的转换,BFS ,一道好题。
#include <iostream>
#include <limits>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <tuple>
#include <queue>
using namespace std;
const int size = 25 + 5;
char s[size][size];
int v[size][size][4][5];
int len[size][size][4][5];
int d[4][3][4] = { {{-1 , 0 , 0 , 1} , {0 , 0 , 2 , 0} , {0 , 0 , 3 , 0}} , //North
{{1 , 0 , 1 , 1} , {0 , 0 , 2 , 0} , {0 , 0 , 3 , 0}} , //South
{{0 , -1 , 2 , 1} , {0 , 0 , 0 , 0} , {0 , 0 , 1 , 0}} , //West
{{0 , 1 , 3 , 1} , {0 , 0 , 0 , 0} , {0 , 0 , 1 , 0}} //East
};
int main()
{
int m , n , cnt = 1;
while(scanf("%d%d" , &m , &n) && m)
{
if(cnt > 1) cout << endl;
getchar();
memset(s , '#' , sizeof(s));
memset(v , 0 , sizeof(v));
memset(len , 0 , sizeof(len));
for(int i = 1 ; i <= m ; ++i)
{
fgets(s[i]+1 , n+2 , stdin);
s[i][n+1] = '#';
}
int sx , sy , fx , fy;
for(int i = 1 ; i <= m ; ++i)
{
for(int j = 1; j <= n ; ++j)
{
if(s[i][j] == 'S') { sx = i , sy = j; }
else if(s[i][j] == 'T') { fx = i , fy = j; }
}
}
int min_len = -1;
queue< tuple<int , int , int , int> > q;
q.push(make_tuple(sx , sy , 0 , 0));
while(!q.empty())
{
auto t = q.front(); q.pop();
int x = get<0>(t);
int y = get<1>(t);
int a = get<2>(t);
int b = get<3>(t);
v[x][y][a][b] = 1;
for(int i = 0 ; i < 3 ; ++i)
{
int tx = x + d[a][i][0];
int ty = y + d[a][i][1];
int ta = d[a][i][2];
int tb = (b + d[a][i][3]) % 5;
if(s[tx][ty] == '#' || v[tx][ty][ta][tb] ) continue;
len[tx][ty][ta][tb] = len[x][y][a][b] + 1;
if(tx == fx && ty == fy && tb == 0)
{
min_len = len[tx][ty][ta][tb]; break;
}
q.push(make_tuple(tx , ty , ta , tb));
}
if(min_len >= 0) break;
}
cout << "Case #" << cnt++ << endl;
if(min_len >=0 ) cout << "minimum time = " << min_len << " sec" << endl;
else cout << "destination not reachable" << endl;
}
return 0;
}