其实吧,就是一个半平面交,而且不用考虑转回来的情况,所以只要极角排序然后用栈即可
给的是点斜式,比极角很方便
至于完整版的半平面交还没写过,看到再说吧
1 var a,b,c,q:array[0..50010] of longint; 2 v:array[0..50010] of boolean; 3 t,i,n:longint; 4 procedure swap(var a,b:longint); 5 var c:longint; 6 begin 7 c:=a; 8 a:=b; 9 b:=c; 10 end; 11 12 procedure sort(l,r: longint); 13 var i,j,x,y: longint; 14 begin 15 i:=l; 16 j:=r; 17 x:=a[(l+r) shr 1]; 18 y:=b[(l+r) shr 1]; 19 repeat 20 while (a[i]<x) or (a[i]=x) and (b[i]>y) do inc(i); 21 while (x<a[j]) or (a[j]=x) and (b[j]<y) do dec(j); 22 if not(i>j) then 23 begin 24 swap(a[i],a[j]); 25 swap(b[i],b[j]); 26 swap(c[i],c[j]); 27 inc(i); 28 j:=j-1; 29 end; 30 until i>j; 31 if l<j then sort(l,j); 32 if i<r then sort(i,r); 33 end; 34 35 procedure push(i:longint); 36 begin 37 while (t-1>0) do 38 if ((b[q[t]]-b[i])/(a[i]-a[q[t]])<=(b[q[t]]-b[q[t-1]])/(a[q[t-1]]-a[q[t]])) then dec(t) 39 else break; //画图可知,如果栈内最后两条直线L2,L1的交点在新加入的直线的右侧,那么L1一定是不可见的 40 inc(t); 41 q[t]:=i; 42 end; 43 44 begin 45 readln(n); 46 for i:=1 to n do 47 begin 48 readln(a[i],b[i]); 49 c[i]:=i; 50 end; 51 sort(1,n); 52 push(1); 53 fillchar(v,sizeof(v),false); 54 for i:=2 to n do 55 if a[i]<>a[i-1] then push(i); 56 for i:=1 to t do 57 v[c[q[i]]]:=true; 58 for i:=1 to n do 59 if v[i] then write(i,' '); 60 writeln; 61 end.