我的思路是用深度搜索,找到所有的四边形然后判断是否为正方形
题目描述
在一个 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))
编码不易,有帮助的话点个赞支持一下吧~~~