这是练习的第一道题(答案是3),通过率还挺高的,但我写了好久,(哭死)记录一下写的过程吧
题目很简单,就是在字符串图像里找X。我一开始的思路是先确定L的取值,L的最大值等于最小边长整除二,然后遍历L,当L=1的时候,那我相当于可以忽略最外边一圈,只用检索里面那一部分,检索完之后再把L+1,检索的部分再缩小一圈
n,m = map(int,input().split()) #这里是行列
M = [[input()] for _ in range(n)] #接收字符串
N = [[] for _ in range(n)]
for i in range(n):
for j in range(m):
N[i].append(M[i][0][j]) #把字符串拆开来存到列表中
count = 0
L = min(m,n)//2 + 1
for i in range(1,L+1): #L的遍历
for r in range(i,n-i):
for c in range(i,m-i):
if (N[r][c] == N[r-i][c-i]) & (N[r][c] == N[r-i][c+i]) & (N[r][c] == N[r+i][c-i]) & (N[r][c] == N[r+i][c+i]): #当周围元素与中心元素一样时,count+1
count += 1
print(count)
但这样的结果只有30%的通过率
分析了一下,发现我这种写法的漏洞,当L遍历到i=2时,他就不会检查i=1了,例如在原题中,“L”这个字符形成的X图形有两个,分别为L=1和L=2,但当我把L=1那层的‘L’改成其他字符时,按理说‘L’不存在X图形了,但我的代码运行结果为2(还有一个是‘Q’的)
所以我决定换一种思路,先遍历元素,然后再遍历L
for r in range(1,n-1): #因为L是从1开始的,所以直接放掉外边一圈
for c in range(1,m-1):
L = min(r, c, n - r, m - c) + 1 #L是通过计算正在遍历的字符距离边界的距离确定的
i = 1 #保证每个字符都是从第一层开始遍历
while i < L:
if (N[r][c] == N[r-i][c-i]) & (N[r][c] == N[r-i][c+i]) & (N[r][c] == N[r+i][c-i]) & (N[r][c] == N[r+i][c+i]):
count += 1
i += 1 #当第一层确定后,就扩大层数
else:
break #当有一层不符后,直接下一个字符
然后我信心满满地去测试,结果只剩下20%了,继续检查后发现L的确定出现错误
因为r和c都是从0开始计数,而m和n代表的是长度,直接相减会出现偏差,例如n=5,r=3时,n-r=2,但画图可知此时r距离边界只有1,所以修改该行代码即可
L = min(r, c, n - r - 1, m - c - 1) + 1
最后拿去测试,100%,nice!第一题终于过了!不容易啊