package main /* BFS 分别从S、E出发,把可达位置分别标记为S、E 遍历过程中判断是否有同一行/列或相邻行/列内既含有S,也含有E */ import ( "fmt" ) type Node struct { i, j int } var nS, nE, nH byte = byte('S'), byte('E'), byte('#') func isAdjoin(a, b int) bool { // 是否相邻 if a > b{ return a - b <= 1 } return b - a <= 1 } func main() { var n, m int fmt.Scanf("%d %d", &n, &m) var k = make([][]byte, n) var s string var S_i, S_j, E_i, E_j int for i := 0; i < n; i++ { fmt.Scanf("%s", &s) k[i] = make([]byte, m) k[i] = []byte(s) for j := 0; j < m; j++ { if k[i][j] == nS { S_i = i S_j = j } if k[i][j] == nE { E_i = i E_j = j } } } if isAdjoin(S_i, E_i) || isAdjoin(S_j, E_j) { // 相邻或同行或同列 fmt.Println("YES") return } var si, sj = make([]bool, n),make([]bool, m) // 记录某行某列是否S可达 si[S_i] = true sj[S_j] = true dist := [][]int{{1, 0}, {-1, 0}, {0, -1}, {0, 1}} // 四个方向操作 var cur Node var ni, nj int // 先从S开始遍历 queue := []Node{{S_i, S_j}} for len(queue) > 0 { cur = queue[0] queue = queue[1:] for _, d := range dist { ni = cur.i + d[0] nj = cur.j + d[1] if ni < 0 || ni >= n || nj < 0 || nj >= m || k[ni][nj] == nS || k[ni][nj] == nH { continue } if k[ni][nj] == nE || isAdjoin(ni, E_i) || isAdjoin(nj, E_j) { // 与E相邻或同行或同列 fmt.Println("YES") return } k[ni][nj] = nS si[ni],sj[nj] = true, true queue = append(queue, Node{ni, nj}) } } // 再从E开始遍历 queue = []Node{{E_i, E_j}} for len(queue) > 0 { cur = queue[0] queue = queue[1:] for _, d := range dist { ni = cur.i + d[0] nj = cur.j + d[1] if ni < 0 || ni >= n || nj < 0 || nj >= m || k[ni][nj] == nE || k[ni][nj] == nH { continue } if k[ni][nj] == nS || si[ni] || (ni-1>=0&&si[ni-1]) || (ni+1<n&&si[ni+1]) || sj[nj] || (nj-1>=0&&sj[nj-1]) || (nj+1<m&&sj[nj+1]) { // 与S可达的位置相邻或同行或同列 fmt.Println("YES") return } k[ni][nj] = nE queue = append(queue, Node{ni, nj}) } } // 都没法满足,无法可达 fmt.Print("NO") }