http://www.acm.cs.ecnu.edu.cn/problem.php?problemid=1990 题目的意思是求出一些点,使得这些点到给定的一些直线的距离相等,只有一个点的时候输出该点,多个点那么输出"Many",没有符合的点那么输出"None",大致的做法是:先用角平分线求出一定量的点(最多4个),然后枚举检查这些点,精度有点搞!!!
#include<iostream>
#include<complex>
#include<cmath>
#include<algorithm>
using namespace std;
typedef complex<double> point;

const double eps = 1e-8;
const double inf = 1e20;
const double pi = acos( -1.0 );
const int maxn = 103;
struct line
  {
point a, b;
 line( ) { }
 line( point u, point v ) : a( u ), b( v ) { }
};
line L[maxn];
bool vis[maxn];

 int dblcmp( double x ) { return ( x < -eps ? -1 : x > eps ); }
 double operator^( point p1, point p2 ) { return imag( conj( p1 ) * p2 ); } // 叉积
 double operator&( point p1, point p2 ) { return real( conj( p1 ) * p2 ); } // 点积
// 两直线交点,求交点之前先判断是否平行
point operator*( line u, line v )
  {
double t = v.a - u.a ^ v.b - u.a;
double s = v.b - u.b ^ v.a - u.b;
return u.a + ( u.b - u.a ) * t / ( t + s );
}
// 点到直线的距离
 double DisPointToLine( point p, line l ) { return fabs( l.a - p ^ l.b - p ) / abs( l.a - l.b ); }
// 判断两直线平行
 bool LineParallel( line u, line v ) { return dblcmp( ( u.a - u.b ^ v.a - v.b ) ) == 0; }
// 直线向左侧平移
line Translation( line l )
  {
point p = ( l.b - l.a ) * point( 0.0, 1000.0 / abs( l.b - l.a ) );
return line( l.a + p, l.b + p );
}
// 以l.a为原点,逆时针旋转90度
line Rotation( line l )
  {
point p = ( l.b - l.a ) * point( 0.0, 1.0 );
return line( l.a, l.a + p );
}
// 求 u 与 v 的一条角平分线
line GetLine( line u, line v )
  {
line l1 = Translation( u );
line l2 = Translation( v );
return line( u * v, l1 * l2 );
}

bool check( point p, int n, double val )
  {
int i;
double D;
for( i = 0; i < n; i++ )
 {
D = DisPointToLine( p, L[i] );
if( dblcmp( D - val ) != 0 )return false;
}
return true;
}

bool same_point( point p1, point p2 )
  {
return dblcmp( imag( p1 ) - imag( p2 ) ) == 0 && dblcmp( real( p1 ) - real( p2 ) ) == 0;
}

int MyUnique( point p[], int n )
  {
int i, len = 1;
for( i = 1; i < n; i++ )
 {
if( !same_point( p[i], p[i-1] ) )
p[len++] = p[i];
}
return len;
}

void solve( int n )
  {
 if( n < 3 ) { printf("Many\n"); return; }
int i, j;
line l[4], u, v, w;
memset( vis, false, sizeof( vis ) );
vis[0] = true;
u = L[0];
for( i = 1; i < n; i++ )
 {
if( !LineParallel( L[0], L[i] ) )
 {
vis[i] = true;
v = L[i];
break;
}
}
 if( i == n ) { printf("None\n"); return; }
l[0] = GetLine( u, v );
l[1] = Rotation( l[0] );
for( i = 1; i < n; i++ )
 {
if( !vis[i] && ( !LineParallel( u, L[i] ) || !LineParallel( v, L[i] ) ) )
 {
vis[i] = true;
w = L[i];
break;
}
}
if( !LineParallel( u, w ) )
 {
l[2] = GetLine( u, w );
l[3] = Rotation( l[2] );
}
else
 {
l[2] = GetLine( v, w );
l[3] = Rotation( l[2] );
}
point p[4];
double val[4];
int len = 0;
 if( !LineParallel( l[0], l[2] ) ) { p[len] = l[0] * l[2]; val[len++] = DisPointToLine( p[len], u ); }
 if( !LineParallel( l[0], l[3] ) ) { p[len] = l[0] * l[3]; val[len++] = DisPointToLine( p[len], u ); }
 if( !LineParallel( l[1], l[2] ) ) { p[len] = l[1] * l[2]; val[len++] = DisPointToLine( p[len], u ); }
 if( !LineParallel( l[1], l[3] ) ) { p[len] = l[1] * l[3]; val[len++] = DisPointToLine( p[len], u ); }
len = MyUnique( p, len );
int cnt = 0;
point P;
for( i = 0; i < len; i++ )
 {
if( check( p[i], n, val[i] ) )
 {
P = p[i];
cnt++;
}
}
if( cnt == 0 )printf("None\n");
else if( cnt == 1 )printf("%.5lf %.5lf\n",P.real( ), P.imag( ) );
else printf("Many\n");
}

int main( )
  {
int i, n;
double x1, x2, y1, y2;
while( scanf("%d",&n) != EOF )
 {
for( i = 0; i < n; i++ )
 {
scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
L[i] = line( point( x1, y1 ), point( x2, y2 ) );
}
solve( n );
}
return 0;
}

|