这题UVA只有50+人过,有那么难么。。。
过了之后成功垫底。。
Total Submissions Users that tried itUsers that solved it
264 70 58
Your best accepted try
Ranking SubmissionRun Time LanguageSubmission Date
54 9156103 0.640 C++ 2011-08-16 08:46:46
这题感觉也算经典题了吧,给你两个集合的点,让你求一条线把这些点分成两部分,使得每一部分都包含每个集合点的一半。
这个问题也简化了不少,这条线必须过0,0点,没有三点共线。
没有三点共线这个条件好啊~~~方便了好多。
本来想啊,给了两点之间角度在1e-6一下,难道要枚举角度么?后来想了想,完全没必要,角度还有浮点误差的 = =、、
直接极角排序后,从第一个点找到对称的不和第一个点在一个半区域的那个点,然后一个一个往下扫描,如下图,圈圈画起来的点是第一条扫描线分起来的区域。。额,这个直接满足题意了。如果不满足的话,就按顺序依次扫描。WA了一次,因为对面的那个点是可能再次回到起点的。需要%n。
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#define MID(x,y) ( ( x + y ) >> 1 )
#define L(x) ( x << 1 )
#define R(x) ( x << 1 | 1 )
#define BUG puts("here!!!")
#define STOP system("pause")
using namespace std;
const int MAX = 30010;
struct point{double x,y; bool flag;};
point p[MAX];
point s;
const double eps = 1e-8;
bool dy(double x,double y) { return x > y + eps;} // x > y
bool xy(double x,double y) { return x < y - eps;} // x < y
bool dyd(double x,double y) { return x > y - eps;} // x >= y
bool xyd(double x,double y) { return x < y + eps;} // x <= y
bool dd(double x,double y) { return fabs( x - y ) < eps;} // x == y
double crossProduct(point a,point b,point c)//向量 ac 在 ab 的方向 顺时针是正
{
return (c.x - a.x)*(b.y - a.y) - (b.x - a.x)*(c.y - a.y);
}
bool cmp(point a,point b)
{
double a1 = atan2(a.y, a.x);
double a2 = atan2(b.y, b.x);
return xy(a1, a2);
}
bool solve(int n,int a,int b)
{
a /= 2; b /= 2;
point beg = p[0];
int ca = 0, cb = 0;
if( p[0].flag == true )
ca++;
else
cb++;
int i;
bool flag = false;
for(i=1; i<n; i++)
{
if( xy(crossProduct(s, beg, p[i]), 0.0) )
{
if( p[i].flag == true )
ca++;
else
cb++;
}
else
{
flag = true;
break;
}
}
if( !flag ) i = 0;
if( ca == a && cb == b ) return true;
for(int k=1; k<n; k++)
{
if( p[k-1].flag == true )
ca--;
else
cb--;
while( xy(crossProduct(s, p[k], p[i]), 0.0) )
{
if( p[i].flag )
ca++;
else
cb++;
i++;
i %= n;
}
if( ca == a && cb == b ) return true;
}
return false;
}
int main()
{
int a,b;
s.x = s.y = 0;
while( ~scanf("%d%d",&a, &b) )
{
if( a == b && a == -1 ) break;
int n = 0;
for(int i=0; i<a; i++)
{
scanf("%lf%lf",&p[n].x, &p[n].y);
p[n++].flag = 1;
}
for(int i=0; i<b; i++)
{
scanf("%lf%lf",&p[n].x, &p[n].y);
p[n++].flag = 0;
}
sort(p, p+n, cmp);
bool ans = solve(n, a, b);
if( ans )
printf("YES\n");
else
printf("NO\n");
}
return 0;
}