python 面试题 牛客_牛客京东面试题数三角形解题思路

题目描述

给出平面上的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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值