LA 4992 && hdu 3761 Jungle Outpost
杭电的有点坑啊。。一直爆内存,后来发现大白的半平面交模板那里 point *p = new point[n]; line *q = new line[n]这里出了问题,应该是在函数里面申请不了比较大的数组,所以爆内存。。我在全局定义了两个数组就不会爆了。。
本来跑了17s多的,后来半平面交sort( l, l + n ) 被我注释了,就跑了9s多,LA上跑了 2s。。应该是输入数据比较好,不用按照极角排序。。然后就是照着大白的想法,二分答案,用半平面交判断是否满足条件。。
输入是按照逆时针输入的,所以用p[i] - p[(i+m+1)%n]表示直线的向量。。
这道题被坑了好久,好伤心。。贴的是在杭电ac的代码
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<string> 5 #include<algorithm> 6 #include<queue> 7 #include<cmath> 8 #include<vector> 9 10 using namespace std; 11 12 #define mnx 50050 13 #define LL long long 14 #define mod 1000000007 15 #define inf 0x3f3f3f3f 16 #define eps 1e-8 17 #define Pi acos(-1.0); 18 #define lson l, m, rt << 1 19 #define rson m+1, r, rt << 1 | 1 20 21 int dcmp( double x ){ 22 if( fabs( x ) < eps ) return 0; 23 return x < 0 ? -1 : 1; 24 } 25 struct point{ 26 double x, y; 27 point( double x = 0, double y = 0 ) : x(x), y(y) {} 28 point operator + ( const point &b ) const{ 29 return point( x + b.x, y + b.y ); 30 } 31 point operator - ( const point &b ) const{ 32 return point( x - b.x, y - b.y ); 33 } 34 point operator * ( const double &k ) const{ 35 return point( x * k, y * k ); 36 } 37 point operator / ( const double &k ) const{ 38 return point( x / k, y / k ); 39 } 40 bool operator < ( const point &b ) const{ 41 return dcmp( x - b.x ) < 0 || dcmp( x - b.x ) == 0 && dcmp( y - b.y ) < 0; 42 } 43 bool operator == ( const point &b ) const{ 44 return dcmp( x - b.x ) == 0 && dcmp( y - b.y ) == 0; 45 } 46 double len(){ 47 return sqrt( x * x + y * y ); 48 } 49 }; 50 typedef point Vector; 51 struct line{ 52 point p; 53 Vector v; 54 double ang; 55 line() {} 56 line( point p, point v ) : p(p), v(v) { 57 ang = atan2( v.y, v.x ); 58 } 59 bool operator < ( const line &b ) const{ 60 return ang < b.ang; 61 } 62 }; 63 double dot( Vector a, Vector b ){ 64 return a.x * b.x + a.y * b.y; 65 } 66 double cross( Vector a, Vector b ){ 67 return a.x * b.y - a.y * b.x; 68 } 69 bool onleft( line l, point p ){ 70 return cross( l.v, p - l.p ) > 0; 71 } 72 point getintersection( line a, line b ){ 73 Vector u = a.p - b.p; 74 double t = cross( b.v, u ) / cross( a.v, b.v ); 75 return a.p + a.v * t; 76 } 77 point pp[mnx]; 78 line q[mnx]; 79 int halfplaneintersection( line *L, int n, point *poly ){ 80 //sort( L, L + n ); 81 int first, last; 82 q[first = last = 0] = L[0]; 83 for( int i = 1; i < n; i++ ){ 84 while( first < last && !onleft( L[i], pp[last-1] ) ) last--; 85 while( first < last && !onleft( L[i], pp[first] ) ) first++; 86 q[++last] = L[i]; 87 if( fabs( cross( q[last].v, q[last-1].v ) ) < eps ){ 88 last--; 89 if( onleft( q[last], L[i].p ) ) q[last] = L[i]; 90 } 91 if( first < last ) pp[last-1] = getintersection( q[last-1], q[last] ); 92 } 93 while( first < last && !onleft( q[first], pp[last-1] ) ) last--; 94 if( last - first <= 1 ) return 0; 95 pp[last] = getintersection( q[last], q[first] ); 96 int m = 0; 97 for( int i = first; i <= last; i++ ){ 98 poly[m++] = pp[i]; 99 } 100 return m; 101 } 102 point p[mnx], poly[mnx]; 103 line l[mnx]; 104 bool check( int n, int m ){ 105 if( n - m <= 2 ) return 1; 106 for( int i = 0; i < n; i++ ){ 107 l[i] = line( p[i], p[i] - p[(i+m+1)%n] ); 108 } 109 int all = halfplaneintersection( l, n, poly ); 110 if( !all ) return 1; 111 else return 0; 112 } 113 int main(){ 114 int n, cas; 115 scanf( "%d", &cas ); 116 while( cas-- ){ 117 scanf( "%d", &n ); 118 for( int i = 0; i < n; i++ ){ 119 scanf( "%lf %lf", &p[i].x, &p[i].y ); 120 } 121 if( n > 50000 ) continue; 122 int l = 0, r = n, ans; 123 while( l < r ){ 124 int m = ( l + r ) >> 1; 125 if( check( n, m ) == 1 ){ 126 ans = m, r = m; 127 } 128 else l = m + 1; 129 } 130 printf( "%d\n", ans ); 131 } 132 return 0; 133 }