平面切分 藍橋杯第十一屆Python組第九題

2021-10-20 07:42:30 字數 1738 閱讀 2889

給定多條直線,詢問這多條直線將平面分成了幾部分?輸入 a 和 b,代表當前直線為y = a * x + b

我們知道一條直線可以把平面分成兩部分,可以理解成這條直線的加入貢獻了乙個新的部分(可能說的不嚴謹,指的是答案加1,因為初始狀態是乙個整的平面)

若用ci[i]表示第i條加入的直線對答案的貢獻

易知ci[1] = 1

若當前加入直線與平面內現存直線存在n個不同交點,則ci[i] = 1 + n

所以最終答案即為ci陣列之和

那麼ci[i]為什麼等於1 + n呢?

簡單思考下,第一條加入的直線勢必會把平面分成兩部分,第二條加入直線如果與第一條平行,那麼這條直線只是在分割前面那兩部分中的一部分,它不會對另一部分產生影響,如下圖所示,用紅色矩形表示整平面,則橙色直線不會對紫色區域產生分割。若不平行,那肯定會對紫色區域進行分割。

注意要維護新加入直線與先前直線不同的交點, 用set即可

import sys

n =int

(input()

)lines =

for i in

range

(n):

a, b =

list

(map

(int

,input()

.split())

)(a, b)

)lines =

list

(set

(lines)

)#這裡是去掉重複直線

n =len

(lines)

defgetnode

(lines1, lines2)

:#得到兩條直線交點,若平行,返回none

a1 = lines1[0]

b1 = lines1[1]

a2 = lines2[0]

b2 = lines2[1]

if a1 - a2 ==0:

return

x =(b2 - b1)

/(a1 - a2)

y = a1 * x + b1

x =round

(x,10

) y =

round

(y,10

)return

(x, y)

ci =[1

]*(n +1)

node =

set(

)for i in

range(1

, n)

: node.clear(

)for j in

range

(i):

tmp = getnode(lines[i]

, lines[j]

)if tmp ==

none

:continue

node.add(tmp)

ci[i]

+=len

(node)

print

(sum

(ci[

:n])+1

)

第十一屆藍橋杯

問題描述 小藍要為一條街的住戶製作門牌號。這條街一共有 2020 位住戶,門牌號從 1 到 2020 編號。小藍製作門牌的方法是先製作 0 到 9 這幾個數字字元,最後根據需要將字 符貼上到門牌上,例如門牌 1017 需要依次貼上字元 1 0 1 7,即需要 1 個 字元 0,2 個字元 1,1 個...

第十一屆藍橋杯 矩陣

問題描述 把 1 2020 放在 2 1010 的矩陣裡。要求同一行中右邊的比左邊大,同一列中下邊的比上邊的大。一共有多少種方案?答案很大,你只需要給出方案數除以 2020 的餘數即可。答案提交 這是一道結果填空題,你只需要算出結果後提交即可。本題的結果為乙個整數,在提交答案時只填寫這個整數,填寫多...

第十一屆藍橋杯 走方格

問題描述 在平面上有一些二維的點陣。這些點的編號就像二維陣列的編號一樣。從上到下依次為第 1 至第 n 行,從左到右依次為第 1 至第 m 列,每乙個點可以用行號和列號來表示。現在有個人站在第 1 行第 1 列,要走到第 n 行第 m 列。只能向右或者向下走。注意,如果行號和列號都是偶數,不能走入這...