题意是重点,监控的范围可以走但要有箱子,会浪费时间
还有就是它所谓的范围2包含中心,深坑啊...........
按照spfa的思想宽搜,比较好写
下面是我千疮百孔的ac代码:
#include <iostream>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <algorithm>
#include <queue>
#define MAX 520
#define INF 0x3f
using namespace std;
int t,n,ex,ey;
int m[MAX][MAX][5];
int used[MAX][MAX][5];
char s[MAX][MAX];
struct Node
{
int t,x,y,wait;
bool operator < ( const Node& a ) const
{
return t > a.t;
}
}tst,st;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,1,-1};
int bfs ( )
{
priority_queue<Node> q;
memset ( used , INF , sizeof ( used ) );
st.t = 0;
st.wait = 0;
q.push ( st );
used[st.x][st.y][0] = 0;
while ( !q.empty() )
{
tst = q.top();
// cout << tst.x << " " << tst.y << endl;
if ( s[tst.x][tst.y] == 'T' ) return tst.t;
q.pop();
for ( int i = 0 ; i < 4 ; i++ )
{
st.x = tst.x + dx[i];
st.y = tst.y + dy[i];
if ( m[st.x][st.y][0] == -1 ) continue;
int tt = tst.t%4;
if ( m[st.x][st.y][tt] == 2 ||
m[tst.x][tst.y][tt] == 2 )
st.t = tst.t + 3;
else st.t = tst.t + 1;
st.wait = 0;
if ( st.t < used[st.x][st.y][st.wait] )
{
q.push ( st );
used[st.x][st.y][st.wait] = st.t;
}
}
st.x = tst.x;
st.y = tst.y;
st.t = tst.t + 1;
st.wait = tst.wait + 1;
if ( st.wait <= 3 && st.t < used[st.x][st.y][st.wait] )
{
q.push ( st );
used[st.x][st.y][st.wait] = st.t;
}
}
return -1;
}
int main ( )
{
scanf ( "%d" , &t );
int c = 1;
while ( t-- )
{
scanf ( "%d" , &n );
memset ( m , -1 , sizeof ( m ) );
for ( int i = 1 ; i <= n ; i++ )
{
scanf ( "%s" , s[i]+1 );
for ( int j = 1 ; j <= n ; j++ )
{
if ( s[i][j] == '.' )
for ( int k = 0 ; k < 4 ; k++ )
m[i][j][k] = 1;
if ( s[i][j] == 'M' )
{
st.x = i , st.y = j;
for ( int k = 0 ; k < 4 ; k++ )
m[i][j][k] = 1;
}
if ( s[i][j] == 'T' )
{
ex = i , ey = j;
for ( int k = 0 ; k < 4 ; k++ )
m[i][j][k] = 1;
}
}
}
for ( int i = 1 ; i <= n ; i++ )
{
//scanf ( "%s" , s[i]+1 );
for ( int j = 1 ; j <= n ; j++ )
{
if ( s[i][j] == 'N' )
for ( int k = 1 ; k < 2 ; k++ )
{
for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
if ( i-k >= 0 && m[i-k][j][0] != -1 )
m[i-k][j][0] = 2;
if ( m[i][j+k][1] != -1 )
m[i][j+k][1] = 2;
if ( m[i+k][j][2] != -1 )
m[i+k][j][2] = 2;
if ( j-k >= 0 && m[i][j-k][3] != -1 )
m[i][j-k][3] = 2;
}
if ( s[i][j] == 'S' )
for ( int k = 1 ; k < 2 ; k++ )
{
for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
if ( m[i+k][j][0] != -1 )
m[i+k][j][0] = 2;
if ( j-k >= 0 && m[i][j-k][1] != -1 )
m[i][j-k][1] = 2;
if ( i-k >= 0 && m[i-k][j][2] != -1 )
m[i-k][j][2] = 2;
if ( m[i][j+k][3] != -1 )
m[i][j+k][3] = 2;
}
if ( s[i][j] == 'W' )
for ( int k = 1 ; k < 2 ; k++ )
{
for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
if ( j-k >= 0 && m[i][j-k][0] != -1 )
m[i][j-k][0] = 2;
if ( i-k >= 0 && m[i-k][j][1] != -1 )
m[i-k][j][1] = 2;
if ( m[i][j+k][2] != -1 )
m[i][j+k][2] = 2;
if ( m[i+k][j][3] != -1 )
m[i+k][j][3] = 2;
}
if ( s[i][j] == 'E' )
for ( int k = 1 ; k < 2 ; k++ )
{
for ( int z = 0 ; z < 4 ; z++ ) m[i][j][z] = 2;
if ( m[i][j+k][0] != -1 )
m[i][j+k][0] = 2;
if ( m[i+k][j][1] != -1 )
m[i+k][j][1] = 2;
if ( j-k >= 0 && m[i][j-k][2] != -1 )
m[i][j-k][2] = 2;
if ( i-k >= 0 && m[i-k][j][3] != -1 )
m[i-k][j][3] = 2;
}
}
}
/*
for ( int k = 0 ; k < 4 ; k++ )
{
cout << "____________________________________" << endl;
for ( int i = 0 ; i <= n+1 ; i++ )
{
for ( int j = 0 ; j <= n+1 ; j++ )
cout << setw(2) << m[i][j][k] << " ";
cout << endl;
}
cout << "____________________________________" << endl;
}
*/
printf ( "Case #%d: %d\n" , c++ , bfs () );
}
}