在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 #includeview code8 #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 }
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...