试题 历届试题 平面切分【第十一届】【省赛】【B组】
资源限制
内存限制:256.0MB C/C++时间限制:1.0s Java时间限制:3.0s Python时间限制:5.0s
问题描述
平面上有 N条直线,其中第 i 条直线是Y=AX+B 。
请计算这些直线将平面分成了几个部分。
输入格式
第一行包含一个整数 N。
以下N行,每行包含两个整数 Ai,Bi。
输出格式
一个整数代表答案。
样例输入
3
1 1
2 2
3 3
样例输出
6
评测用例规模与约定
对于 50% 的评测用例,1≤N≤4, −10≤Ai,Bi≤10。
对于所有评测用例,1≤N≤1000, −100000≤Ai,Bi≤100000。
思路:
对于直线对平面划分的贡献
1.第一条直线固定将一个平面分成两个面。
2.剩下的n-1条直线 i,考虑其和前i-1条直线的交点(要去重)个数cnt,第i条直线对平面划分的贡献是cnt+1。
3.直线三种特殊情况,平行,重合,垂直,一定要考虑清楚
4.不能除0 ,否则会报错,要特判。
5.对于每一条直线,只需记录其交点的x坐标,
上demo:
import bisect as bis
n=int (input())
line=[]
line.append(list(map(int,input().split())))
def fun(a1,b1,a2,b2):
if a1==a2:#斜率相同也就是a相同要特判,否则除0会报错
if (b1==b2):#相同的线没有任何贡献 直接cnt=0 且不加入line数组避免出错
return -2
return -1
if (a1<a2):
a1,a2=a2,a1
b1,b2=b2,b1
x=(b2-b1)/(a1-a2)
return [x]
ans=2
for _ in range(n-1):
a,b=map(int,input().split())
cnt=1
point = []
vis=0
for a1,b1 in line:
mid=fun(a1,b1,a,b)
if (mid==-1):continue #斜率相同也就是a相同要特判,否则除0会报错
elif (mid==-2): #相同的线没有任何贡献 直接cnt=0 且不加入line数组避免出错
cnt=0
vis=1
break
elif (len(point) == 0):
cnt += 1
point.append(mid[0])
continue
ind=bis.bisect_left(point, mid[0])
if ind ==len(point):
cnt+=1
point.append(mid[0])
continue
if (point[ind]==mid[0]):
continue
cnt += 1
bis.insort(point,mid[0])
if vis==1 :continue #线段重复
line.append([a,b])
ans+=cnt
print(ans)
通过情况: