http://124.205.79.250/JudgeOnline/problem?id=3608
旋轉(zhuǎn)卡殼的經(jīng)典題目,看著網(wǎng)上某篇論文寫的,寫了一個(gè)下午還是WA,最后參考了了haozi的代碼,還是WA,原來haozi的代碼中將平行跟其中一種情況合并在一起寫了,精度調(diào)得很高,但是我的精度太低了,調(diào)整精度之后過了。但是我覺得這題的精度是不用那么高的,原因應(yīng)該是出在了,兩種情況的合并上面,后來我改成三種情況,精度就1e-8過了,看來是那哥問題。代碼如下:
pku 3608
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<vector>
5 #include<cstring>
6 #include<complex>
7 using namespace std;
8 typedef complex<double> point;
9 const double eps = 1e-8;
10 const double pi = acos( -1.0 );
11 const double inf = 1e100;
12 vector<point> P, Q;
13
14 double operator ^( const point p1, const point p2 ) { return imag( conj( p1 ) * p2 ); }
15 double operator &( const point p1, const point p2 ) { return real( conj( p1 ) * p2 ); }
16 int dblcmp( double x ) { return ( x < -eps ? -1 : x > eps ); }
17 double min( double x, double y ) { return ( x < y ? x : y ); }
18
19 double DisPointToSeg( const point & p, const point & p1, const point & p2 )
20 {
21 if( dblcmp( p - p1 & p2 - p1 ) < 0 || dblcmp( p - p2 & p1 - p2 ) < 0 )
22 return min( abs( p1 - p ), abs( p2 - p ) );
23 return fabs( p1 - p ^ p2 - p ) / abs( p1 - p2 );
24 }
25
26 double DisPallSeg( point p1, point p2, point p3, point p4 )
27 {
28 return min( min( DisPointToSeg( p1, p3, p4 ), DisPointToSeg( p2, p3, p4 ) ),
29 min( DisPointToSeg( p3, p1, p2 ), DisPointToSeg( p4, p1, p2 ) ) );
30 }
31
32 void changeclockwise( vector<point> & g )
33 {
34 int n = g.size( );
35 if( ( g[1] - g[0] ^ g[2] - g[0] ) < 0 )
36 for( int i = 0; i < n / 2; i++ )
37 swap( g[i], g[n-1-i] );
38 }
39
40 double RC( )
41 {
42 point f0( 1.0, 0 ), f1( -1.0, 0 );
43 point p0, p1, p2, p3;
44 int pn = P.size( ), qn = Q.size( ), k1 = -1, k2 = -1;
45 double ymin = inf, ymax = -inf, angle, ang, ans;
46
47 changeclockwise( P );
48 changeclockwise( Q );
49
50 for( int i = 0; i < pn; i++ )
51 if( ymin > imag( P[i] ) ) ymin = imag( P[i] ), k1 = i;
52 for( int i = 0; i < qn; i++ )
53 if( ymax < imag( Q[i] ) ) ymax = imag( Q[i] ), k2 = i;
54
55 angle = 0.0;
56 ans = inf;
57
58 while( angle <= 140 )
59 {
60 p0 = P[k1]; p1 = P[(k1+1)%pn];
61 p2 = Q[k2]; p3 = Q[(k2+1)%qn];
62 int t = dblcmp( p1 - p0 ^ p3 - p2 );
63 if( t > 0 ) // 旋轉(zhuǎn) p2p3
64 {
65 ang = arg( ( p3 - p2 ) / f1 );
66 f1 = p3 - p2;
67 f0 = -f1;
68 k2 = ( k2 + 1 ) % qn;
69 ans = min( ans, DisPointToSeg( p0, p2, p3 ) );
70 }
71 else if( t == 0 )
72 {
73 ang = arg( ( p1 - p0 ) / f0 );
74 f0 = p1 - p0;
75 f1 = -f0;
76 k1 = ( k1 + 1 ) % pn;
77 k2 = ( k2 + 1 ) % qn;
78 ans = min( ans, DisPallSeg( p0, p1, p2, p3 ) );
79 }
80 else // 平行 && 旋轉(zhuǎn) p0p1, 兩種情況可以合并
81 {
82 ang = arg( ( p1 - p0 ) / f0 );
83 f0 = p1 - p0;
84 f1 = -f0;
85 k1 = ( k1 + 1 ) % pn;
86 ans = min( ans, DisPointToSeg( p2, p0, p1 ) );
87 }
88 angle += ( ang < 0 ? ang + 2 * pi : ang );
89 }
90 return ans;
91 }
92
93 int main( )
94 {
95 int n, m;
96 double x, y, ans;
97 while( scanf("%d%d",&n,&m) && ( n + m ) )
98 {
99 P.clear( );
100 Q.clear( );
101 for( int i = 0; i < n; i++ )
102 {
103 scanf("%lf%lf",&x,&y);
104 P.push_back( point( x, y ) );
105 }
106 for( int i = 0; i < m; i++ )
107 {
108 scanf("%lf%lf",&x,&y);
109 Q.push_back( point( x, y ) );
110 }
111 ans = RC( );
112 printf("%.5lf\n",ans);
113 }
114 }
旋轉(zhuǎn)卡殼的經(jīng)典題目,看著網(wǎng)上某篇論文寫的,寫了一個(gè)下午還是WA,最后參考了了haozi的代碼,還是WA,原來haozi的代碼中將平行跟其中一種情況合并在一起寫了,精度調(diào)得很高,但是我的精度太低了,調(diào)整精度之后過了。但是我覺得這題的精度是不用那么高的,原因應(yīng)該是出在了,兩種情況的合并上面,后來我改成三種情況,精度就1e-8過了,看來是那哥問題。代碼如下:
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<vector>
5 #include<cstring>
6 #include<complex>
7 using namespace std;
8 typedef complex<double> point;
9 const double eps = 1e-8;
10 const double pi = acos( -1.0 );
11 const double inf = 1e100;
12 vector<point> P, Q;
13
14 double operator ^( const point p1, const point p2 ) { return imag( conj( p1 ) * p2 ); }
15 double operator &( const point p1, const point p2 ) { return real( conj( p1 ) * p2 ); }
16 int dblcmp( double x ) { return ( x < -eps ? -1 : x > eps ); }
17 double min( double x, double y ) { return ( x < y ? x : y ); }
18
19 double DisPointToSeg( const point & p, const point & p1, const point & p2 )
20 {
21 if( dblcmp( p - p1 & p2 - p1 ) < 0 || dblcmp( p - p2 & p1 - p2 ) < 0 )
22 return min( abs( p1 - p ), abs( p2 - p ) );
23 return fabs( p1 - p ^ p2 - p ) / abs( p1 - p2 );
24 }
25
26 double DisPallSeg( point p1, point p2, point p3, point p4 )
27 {
28 return min( min( DisPointToSeg( p1, p3, p4 ), DisPointToSeg( p2, p3, p4 ) ),
29 min( DisPointToSeg( p3, p1, p2 ), DisPointToSeg( p4, p1, p2 ) ) );
30 }
31
32 void changeclockwise( vector<point> & g )
33 {
34 int n = g.size( );
35 if( ( g[1] - g[0] ^ g[2] - g[0] ) < 0 )
36 for( int i = 0; i < n / 2; i++ )
37 swap( g[i], g[n-1-i] );
38 }
39
40 double RC( )
41 {
42 point f0( 1.0, 0 ), f1( -1.0, 0 );
43 point p0, p1, p2, p3;
44 int pn = P.size( ), qn = Q.size( ), k1 = -1, k2 = -1;
45 double ymin = inf, ymax = -inf, angle, ang, ans;
46
47 changeclockwise( P );
48 changeclockwise( Q );
49
50 for( int i = 0; i < pn; i++ )
51 if( ymin > imag( P[i] ) ) ymin = imag( P[i] ), k1 = i;
52 for( int i = 0; i < qn; i++ )
53 if( ymax < imag( Q[i] ) ) ymax = imag( Q[i] ), k2 = i;
54
55 angle = 0.0;
56 ans = inf;
57
58 while( angle <= 140 )
59 {
60 p0 = P[k1]; p1 = P[(k1+1)%pn];
61 p2 = Q[k2]; p3 = Q[(k2+1)%qn];
62 int t = dblcmp( p1 - p0 ^ p3 - p2 );
63 if( t > 0 ) // 旋轉(zhuǎn) p2p3
64 {
65 ang = arg( ( p3 - p2 ) / f1 );
66 f1 = p3 - p2;
67 f0 = -f1;
68 k2 = ( k2 + 1 ) % qn;
69 ans = min( ans, DisPointToSeg( p0, p2, p3 ) );
70 }
71 else if( t == 0 )
72 {
73 ang = arg( ( p1 - p0 ) / f0 );
74 f0 = p1 - p0;
75 f1 = -f0;
76 k1 = ( k1 + 1 ) % pn;
77 k2 = ( k2 + 1 ) % qn;
78 ans = min( ans, DisPallSeg( p0, p1, p2, p3 ) );
79 }
80 else // 平行 && 旋轉(zhuǎn) p0p1, 兩種情況可以合并
81 {
82 ang = arg( ( p1 - p0 ) / f0 );
83 f0 = p1 - p0;
84 f1 = -f0;
85 k1 = ( k1 + 1 ) % pn;
86 ans = min( ans, DisPointToSeg( p2, p0, p1 ) );
87 }
88 angle += ( ang < 0 ? ang + 2 * pi : ang );
89 }
90 return ans;
91 }
92
93 int main( )
94 {
95 int n, m;
96 double x, y, ans;
97 while( scanf("%d%d",&n,&m) && ( n + m ) )
98 {
99 P.clear( );
100 Q.clear( );
101 for( int i = 0; i < n; i++ )
102 {
103 scanf("%lf%lf",&x,&y);
104 P.push_back( point( x, y ) );
105 }
106 for( int i = 0; i < m; i++ )
107 {
108 scanf("%lf%lf",&x,&y);
109 Q.push_back( point( x, y ) );
110 }
111 ans = RC( );
112 printf("%.5lf\n",ans);
113 }
114 }

