1007 HNOI2008 水平可見直線

2022-05-12 09:56:44 字數 1707 閱讀 5986

在xoy直角座標平面上有n條直線l1,l2,...ln,若在y值為正無窮大處往下看,能見到li的某個子線段,則稱li為可見的,否則li為被覆蓋的.

例如,對於直線:

l1:y=x; l2:y=-x; l3:y=0

則l1和l2是可見的,l3是被覆蓋的.

給出n條直線,表示成y=ax+b的形式(|a|,|b|<=500000),且n條直線兩兩不重合.求出所有可見的直線.

第一行為n(0 < n < 50000),接下來的n行輸入ai,bi

從小到大輸出可見直線的編號,兩兩中間用空格隔開,最後乙個數字後面也必須有個空格

3-1 0

1 00 0

1 2顯然n^2的演算法會炸。。

然後正解就是先按k排序,然後比較line[i]與sta[top]的交點在sta[top]與sta[top-1]的交點的左邊就彈出棧頂。。。

最後排序即可。。。

1 #include2 #include3 #include4 #include5 #include6 #include7 #include

8 #include9 #include10 #include11 #include

12#define inf 1000000000

13#define maxn 500000+5

14#define maxm 10000+5

15#define eps 1e-10

16#define ll long long

17#define for0(i,n) for(int i=0;i<=(n);i++)

18#define for1(i,n) for(int i=1;i<=(n);i++)

19#define for2(i,x,y) for(int i=(x);i<=(y);i++)

20#define for3(i,x,y) for(int i=(x);i>=(y);i--)

21#define for4(i,x) for(int i=head[x],y=e[i].go;i;i=e[i].next,y=e[i].go)

22using

namespace

std;

23int

n,ans,top;

24double

x[maxn];

25struct

linesta[maxn],l[maxn];

28bool

cmp1(line x,line y)

32bool

cmp2(line x,line y)

35double

cross(line x,line y)

40int

read()

43while(ch>='

0'&&ch<='9')

44return x*f;45}

46int

main()

54 sort(1+l,l+n+1

,cmp1);

55 sta[++top]=l[1];x[1]=-inf;

56 for2(i,2

,n)61 sort(sta+1,sta+top+1

,cmp2);

62 for1(i,top)printf("

%d "

,sta[i].num);

63return0;

64 }

view code

1007 HNOI2008 水平可見直線

time limit 1 sec memory limit 162 mb submit 5879 solved 2238 submit status discuss 在xoy直角座標平面上有n條直線l1,l2,ln,若在y值為正無窮大處往下看,能見到li的某個子線段,則稱li為 可見的,否則li為被...

1007 HNOI2008 水平可見直線

因為要求的是從上方看下來可以看到的直線 畫一下圖可以發現能看見的是上邊的乙個下凸殼 然後就單調棧維護一下斜率就好了 include include include include using namespace std const int n 5e4 5 int n struct line l n ...

1007 HNOI2008 水平可見直線

先對a排序,a相等的話就對b排序 維護乙個棧,每次取棧的頭兩個,和當前的直線相比較 如果當前的直線把頭第乙個遮蔽,就將他出棧,一直到不能遮蔽為止 include include include define maxn 500005 using namespace std intst maxn top...