defto_int(s: str) -> int: if s.isdigit(): returnint(s) elif s.isalpha(): returnord(s) - ord('A') + 10 elif s == '-': return36 else: # s == '*', enter return37 whileTrue: try: r, c = map(int, input().split()) except: break kb = [[to_int(ch) for ch ininput()] for _ inrange(r)] s = [to_int(ch) for ch ininput()] + [37] # 最後需要 Enter 鍵 # 預處理下一個與當前按鍵不同的按鍵 nxt = [[[] for j inrange(c)] for i inrange(r)] for x inrange(r): for y inrange(c): for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)): nx, ny = x + dx, y + dy while0 <= nx < r and0 <= ny < c and kb[nx][ny] == kb[x][y]: nx, ny = nx + dx, ny + dy if0 <= nx < r and0 <= ny < c: nxt[x][y].append((nx, ny)) # BFS ans = float("inf") q = deque([(0, 0, 0, 0)]) visited = [[-1] * c for _ inrange(r)] # 走到 (x, y) 時,已經找到的字元數是多少 while q: x, y, idx, step = q.popleft() if kb[x][y] == s[idx]: # 當前按鍵與目標字元相同 if idx == len(s) - 1: # 找到答案 ans = step + 1 break q.append((x, y, idx+1, step+1)) # 按下當前按鍵,找下一個字元 visited[x][y] = max(visited[x][y], idx+1) else: for nx, ny in nxt[x][y]: if visited[nx][ny] >= idx: # 剪枝,到達 (nx, ny) 時已經找到的字元數比當前多 continue visited[nx][ny] = idx q.append((nx, ny, idx, step+1)) # 移動到 (nx, ny) print(ans)
#include<bits/stdc++.h> usingnamespace std; constint N = 55; #define endl '\n'
structNode { int x, y, idx, step; };
intmain(){ ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); int r, c, x, y, nx, ny, idx, step; vector<pair<int, int>> nxt[N][N]; int visited[N][N]; int DX[4] = {1, -1, 0, 0}, DY[4] = {0, 0, 1, -1}; while (cin >> r >> c){ vector<string> kb(r); for (int i = 0; i < r; i++){ cin >> kb[i]; } string s; cin >> s; s += "*"; // add end mark (enter) // find next key that is different from current key for (int i = 0; i < r; i++){ for (int j = 0; j < c; j++){ nxt[i][j].clear(); for (int k = 0; k < 4; k++){ nx = i + DX[k], ny = j + DY[k]; while (nx >= 0 && nx < r && ny >= 0 && ny < c && kb[nx][ny] == kb[i][j]){ nx += DX[k], ny += DY[k]; } if (nx >= 0 && nx < r && ny >= 0 && ny < c){ // valid nxt[i][j].push_back({nx, ny}); } } } } // BFS int ans = INT_MAX; // visited[i][j] = k means that when we reach (i, j), we have at most input s[k] memset(visited, -1, sizeof(visited)); queue<Node> q; q.push({0, 0, 0, 0}); // (x, y, idx, step) while (!q.empty()){ Node node = q.front(); q.pop(); x = node.x, y = node.y, idx = node.idx, step = node.step; if (kb[x][y] == s[idx]){ if (idx == s.size() - 1){ // reach the end ans = step + 1; break; } q.push({x, y, idx+1, step+1}); // stay at current position, but press the botton visited[x][y] = max(visited[x][y], idx+1); // update visited } else { for (pair<int, int> p : nxt[x][y]){ nx = p.first, ny = p.second; if (visited[nx][ny] >= idx){ // Pruning continue; } visited[nx][ny] = idx; q.push({nx, ny, idx, step+1}); // move to next position } } } cout << ans << endl; } return0; }