import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * @param matrix string字符串 
     * @param rows int整型 
     * @param cols int整型 
     * @param str string字符串 
     * @return bool布尔型
     */
    boolean[] visited;
    static int row, col;
    public boolean hasPath (String matrix, int rows, int cols, String str) {
        // write code here
        // 构建数组
        visited = new boolean[rows * cols]; 
        row = rows;
        col = cols;
        char[] matrixs = matrix.toCharArray();
        char[] strArrs = str.toCharArray();
        for(int i = 0; i < rows; i++) {
            for(int j = 0; j < cols; j++) {
                if(judge(matrixs, strArrs, i, j, 0)) {
                    return true;
                }
            }
        }
        return false;

    }
    // 递归:判断是否能走完, k表示应经匹配k个了
    private boolean judge(char[] mat, char[] str, int i, int j, int k) {
        // 将要访问的数组下标
        int pos = i * col + j;
        // base case,回溯
        if(i < 0 || i >= row || j < 0 || j >= col ||
           mat[pos] != str[k] || visited[pos] == true) {
            return false;
        }
        // 标记访问过
        visited[pos] = true;
        // 当前下标pos能匹配,再判断是否到最后一个
        if(k == str.length - 1) {
            return true;
        }
        // 每次匹配成功,计数+1
        k++;
        // 上下左右
        if(judge(mat, str, i + 1, j, k) ||
          judge(mat, str, i, j + 1, k) ||
          judge(mat, str, i - 1, j, k) ||
          judge(mat, str, i, j - 1, k)) {
            return true;
        }
        // 递归结束下,清除到达过的标记
        visited[pos] = false;
        return false;
    }
}