全相等三角形 蓝桥杯模拟

文章描述了一种名为LQ三角形的几何概念,它在字母矩阵中由等腰直角三角形的边缘部分定义,要求每条边上的字母数量相等且至少为2。当所有边缘字母相同时,称为全相等三角形。给定一个字母矩阵,任务是计算全相等三角形的数量。文章提供了一个基于Python的解决方案,通过检查不同顶点位置的三角形并优化搜索范围来减少计算复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

给定一个字母矩阵,定义一个LQ三角形为某行中连续的几个字母、某列中连续的几个字母和一条45度的斜线中连续的几个字母组成的等腰直角三角形的边缘部分,其中每条边上的字母数量相等且至少为2 。

例如,对于下面的字母矩阵中,所有的字母 L 组成一个LQ三角形,所有字母 Q 组成了一个 LQ 三角形,所有字母 C 也组成了一个 LQ 三角形。

AAAAAAA  

ALLLLLA   

ALQQLAA   

ALQLAAC   

ALLAACC   

ALAACCC

如果一个 LQ 三角形边上的所有字母相等,则称为一个全相等三角形。以三个例子都是全相等三角形。

给定一个字母矩阵,请求其中有多少个全相等三角形。

输入格式

输入第一行包含两个整数 n, m,分别表示字母矩阵的行数和列数。

接下来 n 行,每行 m 个大写字母,为给定的矩阵。

输出格式

输出一行,包含一个整数,表示答案。

样例输入1

3 4

AAAA

ALAQ

ALQQ

样例输出1

4

样例输入2

6 7

AAAAAAA

ALLLLLA

ALQQLAA

ALQLAAC

ALLAACC

ALAACCC

样例输出2

23

评测用例规模与约定

对于50%的评测用例,1 < = n , m < = 10 1<=n,m<=101<=n,m<=10。

对于所有评测用例,1 < = n , m < = 100 1<=n,m<=1001<=n,m<=100。

思路:这道题分四种情况可以使三角形全等

分别是直角顶点在左上角,右上角,左下角,右下角

  1. 当顶点在右下角时

需要判断左顶点和上顶点这条斜边上所有的点是否相等,和左顶点到右下角直角顶点这条边与上顶点到右下角直角顶点这条边上的所有点是否相等

  1. 当顶点在左下角

  1. 当顶点在右上角

  1. 当顶点在左上角

这四种情况思路是一样的,注意的是我们可以求得每行每列最多相同的点的个数,对代码复杂度进行优化

n,m = map(int,input().split())
mp=[]
for i in range(n):
  mp.append(input())
ans=0
def check(x,y,a,b,d):
  if d==0:
    #定右顶点,左顶点为(x,y),上顶点为(a,b)
    while x>=a and y<=b:
      if mp[a][b] != mp[x][y]:return False
      if mp[a][b]==mp[x][y]
      x-=1
      y+=1
  elif d==1:
      #定左顶点,右顶点为(x,y),上顶点为(a,b)
    while x>=a and y>=b:
      if mp[a][b] != mp[x][y]:
        return False
      x-=1
      y-=1
  elif d==2:
      #定右上顶点,左顶点为(x,y),下顶点为(a,b)
    while x<=a and y<=b:
      if mp[a][b] != mp[x][y]:return False
      x+=1
      y+=1
  elif d==3:
      #定左上顶点,右顶点为(x,y),下顶点为(a,b)
    while x<=a and y>=b:
      if mp[a][b] != mp[x][y]:return False
      x+=1
      y-=1
  return True
#得到上下左右最大的数 缩小范围
for i in range(n):
  for j in range(m):
    up,down,left,right=0,0,0,0
    while (i-up)>=0 and mp[i-up][j]==mp[i][j]:
      up+=1
    while (i+down)<n and mp[i+down][j] == mp[i][j]:
      down+=1
    while (j-left)>=0 and mp[i][j-left] == mp[i][j]:
      left+=1
    while (j+right)<m and mp[i][j+right] == mp[i][j]:
      right+=1
#再确定三角形遍历的范围 减少遍历次数
    for k in range(1,min(up,left)):
      if check(i,j-k,i-k,j,0):#当满足这个条件时 说明mp[i][j-1]=mp[i-1][j] 一直到mp[i][j-k]=mp[i-k][j]这些都是一一对应相等的
#从而间接判断出两条直角边都是相等的
        ans+=1
    for k in range(1,min(right,up)):
      if check(i,j+k,i-k,j,1):
        ans+=1
    for k in range(1,min(left,down)):
      if check(i,j-k,i+k,j,2):
        ans+=1
    for k in range(1,min(right,down)):
      if check(i,j+k,i+k,j,3):
        ans+=1
print(ans)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小梁今天敲代码了吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值