Code
略,见Code
比赛的时候只看了看题目,没有具体思路,比赛完,题解说是凸包相交问题,以前没写过。补一发
#include <bits/stdc++.h>
using namespace std;
#define me(x,y) memset(x,y,sizeof x)
#define MIN(x,y) x < y ? x : y
#define MAX(x,y) x > y ? x : y
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e6;
const double INF = 0x3f3f3f3f;
const int MOD = 1e9+7;
const int eps = 1e-8;
const double inf=1e20;
const double pi = acos(-1.0);
const int maxp = 1010;
/**
* Compares a double to zero
*/
int sgn(double x){
if(fabs(x) < eps) return 0;
if(x < 0)return -1;
else return 1;
}
struct Point{
double x,y;
Point(){}
Point(double _x,double _y){x = _x,y = _y;}
void input(){scanf("%lf%lf",&x,&y);}
void output(){printf("%.2f %.2f\n",x,y);}
bool operator == (Point b)const{return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;}
bool operator < (Point b)const{return sgn(x-b.x) == 0 ? sgn(y-b.y)<0 : x<b.x;}
Point operator -(const Point &b)const{return Point(x-b.x,y-b.y);}
/**
* 叉积
*/
double operator ^ (const Point &b)const{return x*b.y-y*b.x;}
/**
* 点积
*/
double operator * (const Point &b)const{return x*b.x+y*b.y;}
/**
* 返回两点间距离
*/
double distance(Point p){return hypot(x-p.x,y-p.y);}
};
struct Line{
Point s,e;
Line(){}
Line(Point _s,Point _e){s = _s;e = _e;}
bool operator == (Line v){return (s == v.s) && (e == v.e);}
/**
* 点在线段上的判断
*/
bool pointonseg(Point p){return sgn((p-s)^(e-s)) == 0 && sgn((p-s)^(e-s)) <= 0;}
void input(){s.input();e.input();}
void adjust(){if(e < s) swap(s,e);}
/**
* 两线段相交判断
* 2规范相交
* 1非规范相交
* 0不相交
*/
int segcrosseg(Line v){
int d1 = sgn((e-s)^(v.s-s));
int d2 = sgn((e-s)^(v.e-s));
int d3 = sgn((v.e-v.s)^(s-v.s));
int d4 = sgn((v.e-v.s)^(e-v.s));
if((d1^d2) == -2 && (d3^d4) == -2)return 2;
return (d1 == 0 && sgn((v.s-s)*(v.s-e)) <= 0) ||
(d2 == 0 && sgn((v.e-s)*(v.e-e)) <= 0) ||
(d3 == 0 && sgn((s-v.s)*(s-v.e)) <= 0) ||
(d4 == 0 && sgn((e-v.s)*(e-v.e)) <= 0);
}
};
struct polygon{
int n;
Point p[maxp];
Line l[maxp];
void getline(){
for(int i = 0; i < n; ++i){
l[i] = Line(p[i],p[(i+1)%n]);
}
}
/**
* 得到凸包,内部点编号为0-n-1,如果有影响判断所有点共点或共线
*/
void getconvex(polygon &convex){
sort(p,p+n);
convex.n = n;
for(int i = 0;i < min(n,2); ++i)convex.p[i] = p[i];
if(convex.n == 2 && (convex.p[0] == convex.p[1]))convex.n--;
if(n <= 2)return ;
int &top = convex.n;
top = 1;
for(int i = 2; i <n ; ++i){
while(top && sgn((convex.p[top]-p[i])^(convex.p[top-1]-p[i])) <= 0){top--;}
convex.p[++top] = p[i];
}
int temp = top;
convex.p[++top] = p[n-2];
for(int i = n-3; i >= 0; i--){
while(top != temp && sgn((convex.p[top]-p[i])^(convex.p[top-1]-p[i])) <= 0)top--;
convex.p[++top] = p[i];
}
if(convex.n == 2 && (convex.p[0] == convex.p[1]))convex.n--;
//convex.norm();
}
/**
* 判断点和任意多边形的关系
* 3点上
* 2边上
* 1内部
* 0外部
*/
int relationpoint(Point q){
for(int i = 0; i < n; ++i){
if(p[i] == q) return 3;
}
getline();
for(int i = 0; i < n; ++i){
if(l[i].pointonseg(q)) return 2;
}
int cnt = 0;
for(int i = 0; i < n; ++i){
int j = (i+1)%n;
int k = sgn((q-p[j])^(p[i]-p[j]));
int u = sgn(p[i].y-q.y);
int v = sgn(p[j].y-q.y);
if(k > 0 && u < 0 && v >= 0) cnt++;
if(k < 0 && v < 0 && u >= 0) cnt--;
}
return cnt!=0;
}
/**
* 判断两凸包相交
*/
bool ConvexHullIntersection(polygon convex){
for(int i = 0; i < convex.n; ++i){
if(relationpoint(convex.p[i])) return true;
}
for(int i = 0; i < n; ++i){
if(convex.relationpoint(p[i])) return true;
}
getline();
convex.getline();
for(int i = 0; i < n; ++i){
for(int j = 0; j < convex.n; ++j){
if(l[i].segcrosseg(convex.l[j])) return true;
}
}
return false;
}
};
polygon co[2];
polygon convex[2];
int main(){
int t;cin>>t;
while(t--){
int n;cin>>n;
int tot_p0=0,tot_p1=0;
for(int i = 1; i <= n; ++i){
int x1,x2,y;
scanf("%d%d%d",&x1,&x2,&y);
if(y < 0) co[1].p[tot_p1++]=Point(x1,x2);
else co[0].p[tot_p0++]=Point(x1,x2);
}
co[0].n=tot_p0;
co[1].n=tot_p1;
co[0].getconvex(convex[0]);
co[1].getconvex(convex[1]);
if(convex[0].ConvexHullIntersection(convex[1])) puts("Infinite loop!");
else puts("Successful!");
}
return 0;
}