其实吧,就是一个半平面交,而且不用考虑转回来的情况,所以只要极角排序然后用栈即可
给的是点斜式,比极角很方便
至于完整版的半平面交还没写过,看到再说吧

 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.
View Code

 

posted on 2015-03-30 19:48  acphile  阅读(101)  评论(0编辑  收藏  举报