地址:http://acm.hdu.edu.cn/showproblem.php?pid=1728
题意:中文。
mark:我真是弱爆了。总体思路就是BFS,只不过不是用步数来限制,而是用转弯次数。注意坐标是先纵后横。。。
先拍了个DFS,理所当然地TLE了。然后拍了个BFS,其实没想清楚就拍了,结果还TLE。想了半天,BFS没理由TLE啊。然后放了2天,今天想清楚了很多细节,又拍了一个BFS,又TLE了。后来发现是加点至队列的时候,如果一个方向上的某点之前已经访问过,则不加入队列这里,直接写了continue,忘记让x和y坐标变到下一个点去了。。。
代码:
# include <stdio.h>
# include <string.h>
int n, m, k ;
char graph[110][110] ;
int vis[110][110] ;
int sx, sy, ex, ey ;
int front, rear ;
int q[110*110][3] ;
int dr[4][2] = {0, 1, 0, -1, 1, 0, -1, 0} ;
int testxy(int x, int y)
{
if (x < 0 || x >= n) return 0 ;
if (y < 0 || y >= m) return 0 ;
if (graph[x][y] == '*') return 0;
return 1 ;
}
void addnode(int x, int y, int d, int step)
{
while (testxy(x, y))
{
if (vis[x][y] == -1)
{
vis[x][y] = step ;
q[rear][0] = x, q[rear][1] = y, q[rear][2] = d ;
rear++ ;
}
x += dr[d][0] ;
y += dr[d][1] ;
}
}
int bfs(int d)
{
int x, y, z;
front = rear = 0 ;
memset (vis, -1, sizeof(vis)) ;
addnode(sx, sy, d, 0) ;
while(front != rear)
{
x = q[front][0], y = q[front][1], z = q[front][2] ;
front ++ ;
if (x == ex && y == ey) return 1 ;
if (vis[x][y] >= k) continue ;
if (z == 0 || z == 1)
{
addnode(x+dr[2][0], y+dr[2][1], 2, vis[x][y]+1) ;
addnode(x+dr[3][0], y+dr[3][1], 3, vis[x][y]+1) ;
}
else
{
addnode(x+dr[0][0], y+dr[0][1], 0, vis[x][y]+1) ;
addnode(x+dr[1][0], y+dr[1][1], 1, vis[x][y]+1) ;
}
}
return 0 ;
}
int main ()
{
int T, i ;
scanf ("%d%*c", &T) ;
while (T--)
{
scanf ("%d %d%*c", &n, &m) ;
for (i = 0 ; i < n ; i++)
scanf ("%s%*c", graph[i]) ;
scanf ("%d %d %d %d %d", &k, &sy, &sx, &ey, &ex) ;
sx--, sy--, ex--, ey-- ;
for (i = 0 ; i < 4 ; i++) if(bfs(i))
{
puts ("yes") ;
break ;
}
if (i >= 4) puts ("no") ;
}
return 0 ;
}