数正方形---蓝桥杯练习

我的思路是用深度搜索,找到所有的四边形然后判断是否为正方形

题目描述

在一个 N×N 的点阵上,取其中 4 个点恰好组成一个正方形的 4 个顶点,一共有多少种不同的取法?

由于结果可能非常大,你只需要输出模 10^9 + 7 的余数。

如上图所示的正方形都是合法的。
加粗样式
输入描述
输入包含一个整数N (2≤N≤10^6)。

输出描述
输出一个整数代表答案。

输入输出样例

输入

	4

输出

	20

思路

用两层for循环确定一个点的x,y坐标,深度搜索找到所有四个点组成的四边形,然后判断是否为正方形,要注意的是四个点中相同的x坐标最多出现两次,y坐标也同理。设计两个字典记录次数可以减少不必要的计算的次数(若次数大于二,至少有三个点在一条直线上)

如何判断四个点是否连成正方形

得到的是四个点的坐标,但我们不知道顺序,所以两个点相连可能是边,也可能是对角线。
但是四个点就有12种排列组合,而且这十二种排列组合意义都是相同的,于是我们只要随机取两个点,恰好那两点是对角的情况。

if (A-B)**2+(a-b)**2==(A-D)**2+(a-d)**2==(B-C)**2+(b-c)**2==(C-D)**2+(c-d)**2:
         if (A-B)*(A-D)+(a-b)*(a-d)==0 and (C-B)*(C-D)+(c-b)*(c-d)==0:  

这种情况有八种排列组合,
A B C D
A D C B
C B A D
C D A B
B A D C
B C D A
D A B C
D C B A
所以最终结果要除以八

代码

import os
import sys

# 请在此输入您的代码
numbers=[]
N=int(input())
x=dict()
y=dict()
Map=[[0 for i in range(N)] for j in range(N)]
All=0
def con(nums,num):
  global All,x,y,numbers
  if len(nums)==4:
     A=nums[0][0]
     a=nums[0][1]
     B=nums[1][0]
     b=nums[1][1]
     C=nums[2][0]
     c=nums[2][1]
     D=nums[3][0]
     d=nums[3][1]
     if (A-B)**2+(a-b)**2==(A-D)**2+(a-d)**2==(B-C)**2+(b-c)**2==(C-D)**2+(c-d)**2:
         if (A-B)*(A-D)+(a-b)*(a-d)==0 and (C-B)*(C-D)+(c-b)*(c-d)==0:                            
             numbers.append([])
             for i in range(len(nums)):
                 numbers[-1].append(nums[i])
             All+=1
     return 
  for i in range(N):
    if i not in x:
        x[i]=1
    else:
        if x[i]>=2:
            continue
        else:
            x[i]+=1
    for j in range(N):
      if j not in y:
         y[j]=1
      else:
         if y[j]>=2:
            continue
         else:
            y[j]+=1
      a=[]
      a.append(i)
      a.append(j)
      if a in nums:
          y[j]-=1
          continue
      nums.append(a)
      num+=1
      con(nums,num)
      num-=1
      del nums[-1]
      y[j]-=1
    x[i]-=1
        
con([],0)
print(int(All//8)%(10**9+7))

编码不易,有帮助的话点个赞支持一下吧~~~

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值