牛客京东面试题数三角形解题思路
题目描述
给出平面上的n个点,现在需要你求出,在这n个点里选3个点能构成一个三角形的方案有几种。
输入描述:
第一行包含一个正整数n,表示平面上有n个点(n <= 100)
第2行到第n + 1行,每行有两个整数,表示这个点的x坐标和y坐标。(所有坐标的绝对值小于等于100,且保证所有坐标不同)
输出描述:
输出一个数,表示能构成三角形的方案数。
解题思路:
开始的时候想偏了,思路很好,
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)