http://124.205.79.250/JudgeOnline/problem?id=1418 最近跟着haozi大牛学习计算几何,第一道圆的离散化的题目。
题目的大致意思是按照时间顺序把许多圆放在平面上,后放的圆可能将先放的圆覆盖掉,最后求露出一部分的圆的个数。
用圆的左右极点 和 圆之间的交点将圆离散化,将x坐标排序之后,从左往右扫描一下,对于每个区间用vis[ ]数组统计一下哪些圆没被完全覆盖。最后遍历一下vis[ ]数组,计算出个数。

pku 1418
1
#include <cstdio>
2
#include <iostream>
3
#include <cmath>
4
#include <complex>
5
#include <algorithm>
6
#include <cstring>
7
#include <queue>
8
#include <set>
9
using namespace std;
10
typedef complex<double> point;
11
12
const int maxn = 103;
13
const double eps = 1e-13;
14
const double inf = 1e100;
15
16
struct node
17

{
18
double y;
19
int id, flag;
20
bool operator<( const node & a )const
21
{
22
return y < a.y;
23
}
24
};
25
26
struct circle
27

{
28
point p;
29
double r;
30
circle( )
{ }
31
circle( point u, double x ) : p( u ), r( x )
{ }
32
};
33
circle c[maxn];
34
vector<double> vec;
35
int vis[maxn];
36
37
double operator ^ ( const point p1, const point p2 )
{ return imag( conj( p1 ) * p2 ); }
38
double operator & ( const point p1, const point p2 )
{ return real( conj( p1 ) * p2 ); }
39
int dblcmp( double x )
{ return ( x < -eps ? -1 : x > eps ); }
40
41
void intersect_circle_circle( circle c1, circle c2, point & p1, point & p2 )
42

{
43
double d = abs( c1.p - c2.p );
44
double s = c1.r * c1.r + d * d - c2.r * c2.r;
45
double t = c2.r * c2.r + d * d - c1.r * c1.r;
46
point p = c1.p + ( c2.p - c1.p ) * s / ( s + t );
47
point p0( imag(c2.p) - imag(c1.p), real(c1.p) - real(c2.p) );
48
double d1 = abs( p - c1.p );
49
double l = abs( p0 );
50
double m = sqrt( c1.r * c1.r - d1 * d1 ) / l;
51
p1 = p + p0 * m;
52
p2 = p - p0 * m;
53
}
54
55
void lisanhua( int n )
56

{
57
vec.clear( );
58
point p1, p2;
59
for( int i = 1; i <= n; i++ )
60
{
61
vec.push_back( real( c[i].p ) + c[i].r );
62
vec.push_back( real( c[i].p ) - c[i].r );
63
}
64
for( int i = 1; i <= n; i++ )
65
{
66
for( int j = i + 1; j <= n; j++ )
67
{
68
double t = fabs( c[i].r - c[j].r );
69
if( dblcmp( c[i].r + c[j].r - abs( c[i].p - c[j].p ) ) < 0 ||
70
dblcmp( t - abs( c[i].p - c[j].p ) ) > 0 )continue;
71
intersect_circle_circle( c[i], c[j], p1, p2 );
72
vec.push_back( real( p1 ) );
73
vec.push_back( real( p2 ) );
74
}
75
}
76
sort( vec.begin( ), vec.end( ) );
77
}
78
79
void solve( double x, int n )
80

{
81
vector<node> V;
82
node tmp;
83
set<int> ID;
84
for( int i = 1; i <= n; i++ )
85
{
86
if( dblcmp( fabs( real( c[i].p ) - x ) - c[i].r ) > 0 )
87
continue;
88
double d = sqrt( c[i].r * c[i].r -
89
( real( c[i].p ) - x ) * ( real( c[i].p ) - x ) );
90
tmp.y = imag( c[i].p ) - d;
91
tmp.id = -i;
92
tmp.flag = 0;
93
V.push_back( tmp );
94
tmp.y = imag( c[i].p ) + d;
95
//tmp.id = i;
96
tmp.flag = 1;
97
V.push_back( tmp );
98
}
99
sort( V.begin( ), V.end( ) );
100
for( int i = 0; i < V.size( ); i++ )
101
{
102
if( ID.size( ) != 0 ) vis[-(*ID.begin())] = 1;
103
if( V[i].flag == 0 ) ID.insert( V[i].id );
104
else ID.erase( V[i].id );
105
if( ID.size( ) != 0 ) vis[-(*ID.begin())] = 1;
106
}
107
}
108
109
int main(int argc, char *argv[])
110

{
111
int n;
112
double x, y, r;
113
while( scanf("%d",&n) && n )
114
{
115
for( int i = 1; i <= n; i++ )
116
{
117
scanf("%lf%lf%lf",&x,&y,&r);
118
c[i] = circle( point( x, y ), r );
119
}
120
lisanhua( n );
121
memset( vis, 0, sizeof( vis ) );
122
for( int i = 1; i < vec.size( ); i++ )
123
{
124
if( dblcmp( vec[i] - vec[i-1] ) == 0 )continue;
125
solve( ( vec[i] + vec[i-1] ) / 2, n );
126
}
127
int ans = 0;
128
for( int i = 1; i <= n; i++ )
129
if( vis[i] )ans++;
130
printf("%d\n",ans);
131
}
132
return 0;
133
}
134