题目描述
给出平面上的n个点,现在需要你求出,在这n个点里选3个点能构成一个三角形的方案有几种。
输入描述:
第一行包含一个正整数n,表示平面上有n个点(n <= 100)
第2行到第n + 1行,每行有两个整数,表示这个点的x坐标和y坐标。(所有坐标的绝对值小于等于100,且保证所有坐标不同)
输出描述:
输出一个数,表示能构成三角形的方案数。
示例1
输入
复制
4
0 0
0 1
1 0
1 1
输出
复制
4
说明
4个点中任意选择3个都能构成三角形
解题思路:
开始的时候想偏了,思路很好,
1、先算出来n个点一个出多少个三角形。有个公式 n*(n-1)*(n-2).
2、再减去三点一线的那些三角形,推导过程有点复杂。
遍历一遍所有的两点间的直线,计算y=kx+b。存储 【k,b】.当然还有注意集中特殊情况。
如果有重复斜率的就累加。
最后循环一遍,把重复的直线的次数,带入一个公式。计算出来,不是三角形的数量。
最后用总数减去 直线三角形数。
上代码,珍藏一下吧。虽说测试超时了。
n = int(input())
arr=[]
for x in range(n):
arr.append(list(map(int,input().split())))
# n = 4
# arr = [[0, 0], [0, 1], [1, 0], [1, 1]]
kblist = [] # 存储两两的k和b
allcount=0 #总数
count=0 #不符合条件的三角形数量
#计算m个点,能出几个三角形
def jisuan(m):
if m<3:
return 0
elif m==3:
return 1
elif m==4:
return 4
elif m==5:
return 20
elif m>5:
return m*(m-1)*(m-2)
for i in range(n-1):
for j in range(i+1, n):
if arr[i][0] == arr[j][0]: #竖线,记录x位置
k,b=arr[i][0],None
elif arr[i][1] == arr[j][1]: #横线,记录y的位置
k, b = None,arr[i][1]
else:#普通的线
k = (arr[i][1] - arr[j][1]) / (arr[i][0] - arr[j][0])
b = arr[j][1] - k * arr[j][0]
#-------入库---------------------------------------------
state=0
for z in range(len(kblist)):
if [k,b]==kblist[z][:2]:
kblist[z][2]+=1
state=1
if state==0:
kblist.append([k, b,1])
#---------------------------------------------------------
for x in kblist:
if x[2]>2:
count+=jisuan(((((x[2]*8+1)**0.5-1)/2)+1))
print(jisuan(n)-count)
解题思路:
最后看了别人的思路,直接写的,哎。
核心思想,判断三点是否在一线,有个算法公式 :利用向量判断三点是否共线 (x1-x2)*(y1-y3) = (y1-y2)*(x1-x3)
n = int(input())
arr=[]
for x in range(n):
arr.append(list(map(int,input().split())))
# 利用向量判断三点是否共线 (x1-x2)*(y1-y3) = (y1-y2)*(x1-x3)
allcount=0 #总数
for x in range(n):
for y in range(x+1,n):
for z in range(y+1,n):
if (arr[x][0]-arr[y][0])*(arr[x][1]-arr[z][1]) != (arr[x][1]-arr[y][1])*(arr[x][0]-arr[z][0]):
allcount+=1
print(allcount)