多组数据:给n条线段 判断是否有一条直线能与所有的线段产生交♂点
首先n=1/n=2显然
然后考虑如果有一种方案是从中间穿过去 那么一定有某种方案
使得这条直线绕某个点旋转某个角度
然后交上一个线段的端点
所以枚举端点对然后去交线段就行
注意有一个交不上就验证下一个 全都不成立再输出no等等
Code:
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cmath> 5 #include<queue> 6 #include<iostream> 7 #define ms(a,b) memset(a,b,sizeof a) 8 #define rep(i,a,n) for(int i = a;i <= n;i++) 9 #define per(i,n,a) for(int i = n;i >= a;i--) 10 #define inf 2147483647 11 using namespace std; 12 typedef long long ll; 13 typedef double D; 14 #define eps 1e-8 15 ll read() { 16 ll as = 0,fu = 1; 17 char c = getchar(); 18 while(c < '0' || c > '9') { 19 if(c == '-') fu = -1; 20 c = getchar(); 21 } 22 while(c >= '0' && c <= '9') { 23 as = as * 10 + c - '0'; 24 c = getchar(); 25 } 26 return as * fu; 27 } 28 //head 29 #define P point 30 struct point { 31 D x,y; 32 point(){} 33 point(D X,D Y):x(X),y(Y){} 34 D len() {return sqrt(x*x+y*y);} 35 D tan() {return y/x;} 36 D sin() {return len() / y;} 37 D cos() {return len() / x;} 38 void read() {scanf("%lf%lf",&x,&y);} 39 void print() {printf("%.2lf %.2lf ",x,y);} 40 friend inline point operator + (const point &a,const point &b) { 41 return point(a.x+b.x,a.y+b.y); 42 } 43 friend inline point operator - (const point &a,const point &b) { 44 return point(a.x-b.x,a.y-b.y); 45 } 46 //放缩 47 friend inline point operator * (const point &a,const D &b) { 48 return point(a.x*b,a.y*b); 49 } 50 //叉积 51 friend inline D operator * (const point &a,const point &b) { 52 return a.x*b.y-a.y*b.x; 53 } 54 //点积 55 friend inline D operator / (const point &a,const point &b) { 56 return a.x*b.x+a.y*b.y; 57 } 58 bool operator == (const point &o) const { 59 return (x == o.x) && (y == o.y); 60 } 61 }; 62 struct yuan { 63 D r,x,y; 64 yuan(){} 65 yuan(int R,int X,int Y):r(R),x(X),y(Y){} 66 }; 67 struct line { 68 point x,y; 69 }; 70 bool ONSEG(point a,point b,point p) { 71 return ((a-b).len() == (a-p).len() + (p-b).len()); 72 } 73 D TRIAREA(point a,point b,point c) { 74 return ((a-b)*(a-c)) / 2.0; 75 } 76 #define ONLINE(a,b,c) (((a-b)*(a-c)) == 0) 77 #define sign(x) (x) > 0 ? 1 : ((x) < 0 ? -1 : 0) 78 // 1 0 -1 79 // 锐 直 钝 80 int ANGDIR(point a,point b,point p) { 81 D ans = (p-a)*(p-b); 82 return sign(ans); 83 } 84 D dis(point a,point b,point p) { 85 if(ANGDIR(b,p,a) == -1) return (p-a).len(); 86 if(ANGDIR(a,p,b) == -1) return (p-b).len(); 87 return ((p-a)*(p-b)) / (a-b).len(); 88 } 89 int cross(P a,P b,P c,P d) { 90 if(ONLINE(a,b,c) ^ ONLINE(a,b,d)) return 1; 91 if(ONLINE(c,d,a) ^ ONLINE(c,d,b)) return 1; 92 if(ONLINE(a,b,c) & ONLINE(a,b,d)) return -1; 93 if(ONLINE(c,d,a) & ONLINE(c,d,b)) return -1; 94 D J1 = ((c-d)*(c-a)) * ((c-d)*(c-b)); 95 D J2 = ((a-b)*(a-c)) * ((a-b)*(a-d)); 96 if(J1 < 0 && J2 < 0) return 1; 97 return 0; 98 } 99 point Cross(point a,point b,point c,point d) { 100 if(ONLINE(a,b,c)) return c; 101 if(ONLINE(a,b,d)) return d; 102 if(ONLINE(c,d,a)) return a; 103 if(ONLINE(c,d,b)) return b; 104 D S1 = (a-c)*(a-d),S2 = (b-d) * (b-c); 105 point tmp = (b-a) * (S1 / (S1+S2)); 106 return a + tmp; 107 } 108 //CP 109 int n; 110 const int N = 2006; 111 point p[N<<1]; 112 113 bool check(int x,int y) { 114 point a,b; 115 rep(k,1,n) { 116 a = p[k-1<<1|1],b = p[k<<1]; 117 if(((a-p[x])*(a-p[y])) * ((b-p[x])*(b-p[y])) > 0.0) return 0; 118 } 119 return 1; 120 } 121 122 bool solve() { 123 n = read(); 124 rep(i,1,n<<1) scanf("%lf%lf",&p[i].x,&p[i].y); 125 rep(i,1,n<<1) rep(j,i+1,n<<1) { 126 if(p[i] == p[j]) continue; 127 if(check(i,j)) return 1; 128 } 129 return 0; 130 } 131 132 int main() { 133 int T = read(); 134 while(T--) solve() ? puts("Yes!") : puts("No!"); 135 return 0; 136 }
依然一大堆函数没用qwq