题意:训练指南283页
wa代码:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <cmath>
- #include <vector>
- #include <queue>
- #include <map>
- #include <algorithm>
- #include <set>
- #define MM(a) memset(a,0,sizeof(a))
- typedef long long ll;
- typedef unsigned long long ULL;
- const double eps = 1e-14;
- const int inf = 0x3f3f3f3f;
- const double pi=acos(-1);
- using namespace std;
- struct Point {
- double x, y;
- double ang;
- Point() {}
- Point(double x,double y) {
- this->x = x;
- this->y = y;
- }
- void read() {
- scanf("%lf %lf", &x, &y);
- }
- bool operator <(const Point w) const
- {
- if(this->x==w.x) return this->y<w.y;
- else return this->x<w.x;
- }
- };
- typedef Point Vector;
- /*
- struct Line{
- Point a;
- Point v,nor;
- double ang;
- Line(){};
- Line(Point u,Vector w):a(u),v(w){};
- bool operator <(const Line q) const{
- return this->ang<q.ang;
- }
- };
- struct Circle {
- Point c;
- double r;
- Circle(){};
- Circle(Point c, double r) {
- this->c = c;
- this->r = r;
- }
- Point point(double a) {
- return Point(c.x + cos(a) * r, c.y + sin(a) * r);
- }
- };
- */
- Vector operator + (Vector A, Vector B) {
- return Vector(A.x + B.x, A.y + B.y);
- }
- Vector operator - (Vector A, Vector B) {
- return Vector(A.x - B.x, A.y - B.y);
- }
- Vector operator * (Vector A, double p) {
- return Vector(A.x * p, A.y * p);
- }
- Vector operator / (Vector A, double p) {
- return Vector(A.x / p, A.y / p);
- }
- const double PI = acos(-1.0);
- int dcmp(double x) {
- if (fabs(x) < eps) return 0;
- else return x < 0 ? -1 : 1;
- }
- bool operator == (const Point& a, const Point& b) {
- return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
- }
- bool operator < (const Point& a, const Point& b) {
- return a.x < b.x || (a.x == b.x && a.y < b.y);
- }
- double torad(double ang)
- {
- return ang/180*pi;
- }
- double Dot(Vector A, Vector B) {return A.x * B.x + A.y * B.y;} //点积
- double Length(Vector A) {return sqrt(Dot(A, A));} //向量的模
- double Angle(Vector A, Vector B) {return acos(Dot(A, B) / Length(A) / Length(B));} //向量夹角
- double Cross(Vector A, Vector B) {return A.x * B.y - A.y * B.x;} //叉积
- double Area2(Point A, Point B, Point C) {return Cross(B - A, C - A);} //有向面积
- double angle(Vector v) {return atan2(v.y, v.x);}
- Point GetLineIntersection(Point P, Vector v, Point Q, Vector w) {
- Vector u = P - Q;
- double t = Cross(w, u) / Cross(v, w);
- return P + v * t;
- }
- Vector Rotate(Vector A, double rad) {
- return Vector(A.x * cos(rad) - A.y * sin(rad), A.x * sin(rad) + A.y * cos(rad));
- }
- double DistanceToLine(Point P, Point A, Point B) {
- Vector v1 = B - A, v2 = P - A;
- return fabs(Cross(v1, v2)) / Length(v1);
- }
- //线段的规范相交
- bool SegmentProperIntersection(Point a1, Point a2, Point b1, Point b2) {
- double c1 = Cross(a2 - a1, b1 - a1), c2 = Cross(a2 - a1, b2 - a1),
- c3 = Cross(b2 - b1, a1 - b1), c4 = Cross(b2 - b1, a2 - b1);
- return dcmp(c1) * dcmp(c2) < 0 && dcmp(c3) * dcmp(c4) < 0;
- }
- //点在线段上(不含端点)
- bool OnSegment(Point p, Point a1, Point a2) {
- return dcmp(Cross(a1 - p, a2 - p)) == 0 && dcmp(Dot(a1 - p, a2 - p))<0;
- }
- //线段不规范相交 (自己写的)
- bool SegmentinProperIntersection(Point a1, Point a2, Point b1, Point b2)
- {
- if(SegmentProperIntersection(a1, a2, b1,b2))
- return 1;
- if(OnSegment(b1, a1, a2))
- return 1;
- if(OnSegment(b2, a1, a2))
- return 1;
- return 0;
- }
- Point p[1005];
- Vector v[105];
- int n,num,f[505][505],vis[505];
- vector<Point> q;
- bool Onanysegment(Point w)
- {
- for(int i=0;i<n;i++)
- if(OnSegment(w,p[i],p[i+n]))
- return true;
- return false;
- }
- bool Intercetwithangsegment(Point a,Point b)
- {
- for(int i=0;i<n;i++)
- if(SegmentProperIntersection(a,b,p[i],p[i+n]))
- return true;
- return false;
- }
- void init()
- {
- memset(f,0,sizeof(f));
- memset(vis,0,sizeof(vis));
- q.clear();
- p[2*n]=Point(0,0);p[2*n+1]=Point(1000,1000);
- q.push_back(p[2*n]);q.push_back(p[2*n+1]);
- for(int i=0;i<=2*n-1;i++)
- if(!Onanysegment(p[i]))
- q.push_back(p[i]);//对于处在线段中间的点,不进入构图,否则会错,想像一下,两条线段共端点且共线
- num=q.size();
- for(int i=0;i<num;i++)
- for(int j=i+1;j<num;j++)
- if(!Intercetwithangsegment(q[i],q[j]))
- f[j][i]=f[i][j]=1;//说明这两个点可以直接到达
- //for(int i=0;i<num;i++)
- // for(int j=0;j<num;j++)
- //cout<<i<<" "<<j<<" "<<f[i][j]<<endl;
- }
- bool dfs(int cur)
- {
- // printf("cur:%d\n",cur);
- if(cur==1) return true;
- vis[cur]=1;
- for(int i=0;i<num;i++)
- if(!vis[i]&&f[cur][i]&&dfs(i))//dfs的标准格式
- return true;
- return false;
- }
- void solve()
- {
- if(dfs(0)) printf("no\n");
- else printf("yes\n");
- }
- int main()
- {
- while(~scanf("%d",&n)&&n)
- {
- for(int i=0;i<n;i++)
- {
- p[i].read();p[i+n].read();
- v[i]=(p[i+n]-p[i])/(Length(p[i+n]-p[i]));
- p[i]=p[i]-v[i]*1e-5;
- p[i+n]=p[i+n]+v[i]*1e-5;//进行端点的微小扰动
- }
- init();
- solve();
- }
- return 0;
- }