傳送門
題目描述:
在 xo
yxoy
xoy 直角座標平面上有 n
nn 條直線 l1,
l2,.
..,l
nl_1,l_2,...,l_n
l1,l2
,..
.,ln
,若在 y
yy 值為正無窮大處往下看,能見到 l
il_i
li 的某個子線段,則稱 l
il_i
li 為可見的,否則 l
il_i
li 為被覆蓋的。
例如,對於直線 l
1l_1
l1:y=x
y=xy=
x;l2
l_2l2
:y=−x
y=-x
y=−x
;l
3l_3
l3:y=0
y=0y=
0,則 l
1l_1
l1 和 l
2l_2
l2 是可見的,l
3l_3
l3 是被覆蓋的。給出 n
nn 條直線,表示成 y=a
x+
by=ax+b
y=ax+b
的形式(∣a∣
,∣b∣
|a|,|b|
∣a∣,∣b
∣ ≤ 500000
500000
500000
),且 n
nn 條直線兩兩不重合。求出所有可見的直線.
輸入格式:
第一行為 nnn(
0<
n<
50000
)(0 < n < 50000)
(0<
n<50
000)
,接下來的 n
nn 行輸入 ai,
bi
a_i,b_i
ai,bi
輸出格式:
從小到大輸出可見直線的編號,兩兩中間用空格隔開,最後乙個數字後面也必須有個空格
樣例資料:輸入
3-1 0
1 00 0 輸出
1 2
其實看這道題的題意,應該還是很容易可以想到半平面交吧
還是按照斜率大小排序,每次加新線的時候就比較一下交點位置,然後判斷是否需要彈掉棧頂
不過這道題比半平面交模板不同的是不用彈掉隊首和隊尾(因為它們肯定能被看見)
注意這道題有平行線的情況,我們只用保留 b
bb 值最大的那條
#include
#include
#include
#include
#define n 50005
#define eps 1e-8
using
namespace std;
struct line
l[n]
,sta[n]
;bool
comp1
(const line &p,
const line &q)
bool
comp2
(const line &p,
const line &q)
double
interx
(line a,line b)
intmain()
sort
(l+1
,l+n+
1,comp1)
;int num=
0,top=0;
sta[
++top]
=l[1];
for(i=
2;i<=n;
++i)
sort
(sta+
1,sta+top+
1,comp2)
;for
(i=1
;i<=top;
++i)
printf
("%d "
,sta[i]
.id)
;return0;
}
HNOI 2008 水平可見直線
hnoi 2008 水平可見直線 在 xoy 直角座標平面上有n條直線 l1,l2,ln,若在y 值為正無窮大處往下看,能見到 li的某個子線段,則稱 li為可見的,否則 li為被遮蓋的。例如,對於直線 l1 y x l2 y x l3 y 0 則 l1和l2是可見的,l3是被遮蓋的。給出 n 條直...
HNOI2008 水平可見直線
luogu 給定若干條直線 都是 y ax b 的形式 求從上往下看所有可以看到的直線,從小往大輸出編號 n le 50000 a b le 500000 從上往下看,若干條直線構成的半平面交的部分才是可見的 聽說直接做半平面交可以 o n log n 做,但是我不會 y kx b 對於乙個 x 只...
HNOI2008 水平可見直線
傳送門 這道題我自己想了想 不過並沒有想出什麼很好的方法。我們簡單一點考慮,問題可以轉化成求所有在最上面的直線的那個集合中有哪些直線。我們知道斜率最大 接近正無窮 和斜率最小 接近負無窮 的是肯定要被保留下來的,而且還是在最兩側的兩條直線。那麼對於一般的直線,我們考慮一下。如上圖,這兩條直線都是可見...