首页 > 试题广场 >

字符迷阵

[编程题]字符迷阵
  • 热度指数:7144 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 64M,其他语言128M
  • 算法知识视频讲解
注意:本题允许使用C/C++/Java/python进行解答,其他编程语言提交均视作无效处理。

字符迷阵是一种经典的智力游戏。玩家需要在给定的矩形的字符迷阵中寻找特定的单词。
在这题的规则中,单词是如下规定的:
1. 在字符迷阵中选取一个字符作为单词的开头;
2. 选取右方、下方、或右下45度方向作为单词的延伸方向;
3. 以开头的字符,以选定的延伸方向,把连续得到的若干字符拼接在一起,则称为一个单词

以图1为例,如果要在其中寻找单词"WORD",则绿色框所标示的都是合法的方案,而红色框所标示的都是不合法的方案。
现在的问题是,给出一个字符迷阵,及一个要寻找的单词,问能在字符迷阵中找到多少个该单词的合法方案。注意合法方案是可以重叠的,如图1所示的字符迷阵,其中单词"WORD"的合法方案有4种。

输入描述:
输入的第一行为一个正整数T,表示测试数据组数。 接下来有T组数据。每组数据的第一行包括两个整数m和n,表示字符迷阵的行数和列数。接下来有m行,每一行为一个长度为n的字符串,按顺序表示每一行之中的字符。再接下来还有一行包括一个字符串,表示要寻找的单词。  数据范围: 对于所有数据,都满足1<=T<=9,且输入的所有位于字符迷阵和单词中的字符都为大写字母。要寻找的单词最短为2个字符,最长为9个字符。字符迷阵和行列数,最小为1,最多为99。 对于其中50%的数据文件,字符迷阵的行列数更限制为最多为20。


输出描述:
对于每一组数据,输出一行,包含一个整数,为在给定的字符迷阵中找到给定的单词的合法方案数。
示例1

输入

3
10 10
AAAAAADROW
WORDBBBBBB
OCCCWCCCCC
RFFFFOFFFF
DHHHHHRHHH
ZWZVVVVDID
ZOZVXXDKIR
ZRZVXRXKIO
ZDZVOXXKIW
ZZZWXXXKIK
WORD
3 3
AAA
AAA
AAA
AA
5 8
WORDSWOR
ORDSWORD
RDSWORDS
DSWORDSW
SWORDSWO
SWORD

输出

4
16
5
注意:只能固定一个方向走。。。。。。。
直接定义三个走方向的函数,然后判断走的距离。
def right(i,j):                          #固定往右走
    num=0
    while i>=0 and i<=row-1 and j>=0 and j<=col-1 and  num<=LW-1 and  word[num]==mat[i][j]:
        num+=1
        j+=1 
    if num==LW:return True  
    return False   
def down(i,j):                           #固定往下走
    num=0
    while i>=0 and i<=row-1 and j>=0 and j<=col-1 and  num<=LW-1 and  word[num]==mat[i][j]:
        num+=1
        i+=1  
    if num==LW:return True  
    return False   
def rdown(i,j):                         #固定往右下走
    num=0
    while i>=0 and i<=row-1 and j>=0 and j<=col-1 and  num<=LW-1 and  word[num]==mat[i][j]:
        num+=1
        j+=1
        i+=1  
    if num==LW:return True  
    return False   

    
T=int(input())          #T组测试用例
for t in range(T): 
    row,col=map(int,input().strip().split())   #row,col记录行数和列数
    mat=[]
    for r in range(row):
        tmp=input().strip() 
        mat.append(tmp) 
    word=input().strip()                       #word存储需要寻找的单词
    if row<=1 and col<=1:                      #特例输入 
        print(0)
        continue
    ans,LW=0,len(word) 
    for i in range(row):
        for j in range(col):
            if mat[i][j]==word[0]:
                if right(i, j):ans+=1 
                if down(i, j):ans+=1
                if rdown(i, j):ans+=1
    print(ans)


编辑于 2021-08-20 11:13:42 回复(0)
固定方向DFS,外面三层循环,行,列,方向。里面做一次DFS。
k = int(input())
for _ in range(k):
    m,n= map(int,input().split())
    parten = []
    for i in range(m):
        tmp = []
        ss = input()
        for j in range(n):
            tmp.append(ss[j])
        parten.append(tmp)
    word = input()       
    def dfs(parten,word,i,j,c,dx,dy):
        if not word:
            c+=1                    
            return c
        if i<0 or i>=len(parten) or j<0 or j>=len(parten[0]) :
            return c
        if parten[i][j]==word[0]:
            c = dfs(parten,word[1:],i+dx,j+dy,c,dx,dy)
        return c

    dx,dy,ans = [0,1,1],[1,0,1],0
    for i in range(m):
        for j in range(n):
            for t in range(3):
                num = dfs(parten,word,i,j,0,dx[t],dy[t])
                ans += num
    print(ans)


编辑于 2020-04-21 16:15:15 回复(0)
def find_words(matrix, word):
    count = 0
    for i in range(len(matrix)):
        for j in range((len(matrix[0]))):
            if matrix[i][j] == word[0]:
                if matrix[i][j:j+len(word)] == word:
                    count += 1
                if ''.join([k[j] for k in matrix[i:i+len(word)]])== word:
                    count += 1
                if j + len(word) <= len(matrix[0]) and i + len(word) <= len(matrix) and  ''.join([matrix[i+k][j+k] for k in range(len(word))]) == word:
                    count += 1
    return count

n = int(input())
data = []
for i in range(n):
    length, _ = map(int, input().split())
    temp = []
    temp.append([input() for i in range(length)])
    temp.append(input())
    data.append(temp)
for matrix, word in data:
    print(find_words(matrix, word))
直接两个for不搞dfs了
发表于 2019-10-07 23:25:42 回复(0)
暴力破解法,比较耗时,但容易理解和代码实现
# 暴力破解法   
#  注意:1.当剩余行列不足要查找单词长度时,对应的下方和右下方一定不存在要查找的单词
#       2.注意一行中可能会多次出现要查找单词的首字母
t = int(input()) # 测试数据组数
for _ in range(t):
    m,n = map(int,input().split()) #读取行数和列数
    matrix = [] # 用于存放字符矩阵
    for _ in range(m): #读取字符矩阵
        matrix.append(input())
    word = input() # 读取要查找的单词
    length = len(word) #要查找单词的长度
    res = 0
    for i in range(m): #按列查找
        index = matrix[i].find(word[0]) #查找首字母出现在该行的位置
        while index != -1: #首字母出现在该行,则分别向右、向下以及向右下三个方向进行查找
            if matrix[i].find(word,index,index+length) != -1:  #向右
                res += 1
            if m - i >= length: # 只有当剩余行长度大于等于要查找单词长度时,才有可能在下方存在要查找单词
                j = 1  #向下
                while j < length: 
                    if matrix[i + j][index] != word[j]:
                        j = -1
                        break
                    j += 1
                if j != -1:
                    res += 1
                if n - index >= length:# 只有当剩余行和列长度均大于等于要查找单词长度时,才有可能在右下方存在要查找单词
                    j = 1  #向右下
                    while j < length:
                        if matrix[i + j][index +j] != word[j]:
                            j = -1
                            break
                        j += 1
                    if j != -1:
                        res += 1
            matrix[i] = matrix[i][:index] + 'a' + matrix[i][index + 1:]
            index = matrix[i].find(word[0])
    print(res)


发表于 2019-08-19 21:22:12 回复(0)
""""
固定方向的深度搜索
"""
import sys


def dfs(maze, x, y, word, t):
    if not word:
        return True
    move = [[1, 0], [0, 1], [1, 1]]
    x, y = x + move[t][0], y + move[t][1]
    if x < len(maze) and y < len(maze[0]):
        if maze[x][y] == word[0]:
            return dfs(maze, x, y, word[1:], t)
        else:
            return False
    return False


if __name__ == "__main__":
    # sys.stdin = open("input.txt", "r")
    T = int(input().strip())
    for _ in range(T):
        n, m = list(map(int, input().strip().split()))
        maze = []
        for _ in range(n):
            maze.append(input().strip())
        word = input().strip()
        ans = 0
        for i in range(n):
            for j in range(m):
                if maze[i][j] == word[0]:
                    for t in range(3):
                        if dfs(maze, i, j, word[1:], t):
                            ans += 1
        print(ans)

发表于 2019-07-13 10:40:23 回复(0)