标签:
POJ 2653 求最上面覆盖的线段
用一个set维护最上面的线段。删除,插入log(n)。删完set里的数后马上it++
主要是查看线段是否交。首先两个线段的矩形要相交。
然后判断一条线段的两个端点是否跨过另外一条线段所在的直线(用叉积乘积<0判断)
同理另外一条也要检查。
1 #include <cstring> 2 #include <cstdio> 3 #include <algorithm> 4 #include <iostream> 5 #include <cmath> 6 #include <set> 7 using namespace std; 8 const int Inf=0x3f3f3f3f; 9 const double eps=1e-8; 10 int n; 11 struct Vector 12 { 13 double x,y; 14 Vector(double x=0,double y=0):x(x),y(y){} 15 }P[100100],Q[100100]; 16 inline double Min(double A,double B) {return A>B?B:A;} 17 inline double Max(double A,double B) {return A>B?A:B;} 18 inline Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x,A.y-B.y);} 19 inline Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x,A.y+B.y);} 20 inline Vector operator * (Vector A,double p) {return Vector(A.x*p,A.y*p);} 21 inline double Slope(Vector A) {if (fabs(A.x)<eps) return Inf; return A.y/A.x;} 22 inline double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} 23 inline double Area2(Vector A,Vector B,Vector C) {return Cross(B-A,C-A);} 24 inline double Length(Vector A) {return sqrt(A.x*A.x+A.y*A.y);} 25 inline Vector GetLineInsersection(Vector P,Vector v,Vector Q,Vector w) 26 { 27 Vector u=P-Q; 28 double t=Cross(w,u)/Cross(v,w); 29 return P+v*t; 30 } 31 inline bool Check(Vector A,Vector B,Vector C,Vector D) 32 { 33 if (Max(A.x,B.x)<Min(C.x,D.x)) return false; 34 if (Min(A.x,B.x)>Max(C.x,D.x)) return false; 35 if (Max(A.y,B.y)<Min(C.y,D.y)) return false; 36 if (Min(A.y,B.y)>Max(C.y,D.y)) return false; 37 if (Area2(C,A,B)*Area2(D,A,B)>eps) return false; 38 if (Area2(A,C,D)*Area2(B,C,D)>eps) return false; 39 return true; 40 } 41 int main() 42 { 43 // freopen("c.in","r",stdin); 44 while (scanf("%d",&n)!=EOF) 45 { 46 if (n==0) break; 47 set<int> S; 48 for (int i=1;i<=n;i++) 49 { 50 scanf("%lf%lf%lf%lf",&P[i].x,&P[i].y,&Q[i].x,&Q[i].y); 51 set<int>::iterator it; 52 for (it=S.begin();it!=S.end();) 53 { 54 if (Check(P[*it],Q[*it],P[i],Q[i])) S.erase(it++); 55 else it++; 56 } 57 S.insert(i); 58 } 59 printf("Top sticks:"); 60 set<int>::iterator it=S.begin(); 61 printf(" %d",*it++); 62 for (it;it!=S.end();it++) printf(", %d",*it); 63 puts("."); 64 } 65 return 0; 66 }
POJ 1556 求最短路径
同理判断叉积即可,最后用Floyd求最短路即可
1 #include <cstdio> 2 #include <cmath> 3 const double eps=1e-8; 4 const int Inf=0x3f3f3f3f; 5 struct Vector 6 { 7 double x,y; 8 Vector(double x=0,double y=0):x(x),y(y){} 9 }P[200]; 10 int n; 11 double a1,a2,b1,b2,x,f[200][200]; 12 inline Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x,A.y-B.y);} 13 inline Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x,A.y+B.y);} 14 inline Vector operator * (Vector A,double p) {return Vector(A.x*p,A.y*p);} 15 inline double Slope(Vector A) {if (fabs(A.x)<eps) return Inf; return A.y/A.x;} 16 inline double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} 17 inline double Area2(Vector A,Vector B,Vector C) {return Cross(B-A,C-A);} 18 inline double Length(Vector A) {return sqrt(A.x*A.x+A.y*A.y);} 19 inline double Min(double A,double B) {return A>B?B:A;} 20 inline Vector GetLineInsersection(Vector P,Vector v,Vector Q,Vector w) 21 { 22 Vector u=P-Q; 23 double t=Cross(w,u)/Cross(v,w); 24 return P+v*t; 25 } 26 inline bool Check(int u,int v) 27 { 28 if (fabs(P[u].x-P[v].x)<eps) return false; 29 for (int i=u+1;i<=v-1;i++) 30 { 31 if (fabs(P[u].x-P[i].x)<eps || fabs(P[v].x-P[i].x)<eps) continue; 32 Vector T; 33 if (i%4==1) 34 { 35 T=Vector(P[i].x,0); 36 if (Area2(T,P[u],P[v])*Area2(P[i],P[u],P[v])<0) return false; 37 } 38 if (i%4==0) 39 { 40 T=Vector(P[i].x,10); 41 if (Area2(T,P[u],P[v])*Area2(P[i],P[u],P[v])<0) return false; 42 } 43 if (i%4==2) 44 { 45 T=Vector(P[i+1].x,P[i+1].y); 46 if (Area2(T,P[u],P[v])*Area2(P[i],P[u],P[v])<0) return false; 47 } 48 } 49 return true; 50 } 51 52 int main() 53 { 54 // freopen("c.in","r",stdin); 55 while (scanf("%d",&n)!=EOF) 56 { 57 if (n==-1) break; 58 for (int i=0;i<n;i++) 59 { 60 scanf("%lf%lf%lf%lf%lf",&x,&a1,&b1,&a2,&b2); 61 P[i*4+1]=Vector(x,a1); 62 P[i*4+2]=Vector(x,b1); 63 P[i*4+3]=Vector(x,a2); 64 P[i*4+4]=Vector(x,b2); 65 } 66 P[0]=Vector(0,5); 67 P[n*4+1]=Vector(10,5); 68 for (int i=0;i<=4*n+1;i++) 69 for (int j=0;j<=4*n+1;j++) f[i][j]=Inf; 70 for (int i=0;i<=n*4+1;i++) 71 for (int j=i+1;j<=n*4+1;j++) 72 if (Check(i,j)) 73 f[i][j]=f[j][i]=Length(P[i]-P[j]); 74 75 for (int k=0;k<=4*n+1;k++) 76 for (int i=0;i<=4*n+1;i++) 77 for (int j=0;j<=4*n+1;j++) 78 if (i!=j && j!=k) f[i][j]=Min(f[i][j],f[i][k]+f[k][j]); 79 printf("%.2f\n",f[0][4*n+1]); 80 } 81 return 0; 82 }
POJ 1269 判断直线是否平行,共线或求交点
平行和共线slope相等,共线时有向面积为0
求交点用向量求交
1 #include <cstdio> 2 #include <cmath> 3 const double eps=1e-8; 4 const int Inf=0x3f3f3f3f; 5 struct Vector 6 { 7 double x,y; 8 Vector(double x=0,double y=0):x(x),y(y){} 9 }P[2],Q[2]; 10 int n; 11 double x,y; 12 inline Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x,A.y-B.y);} 13 inline Vector operator + (Vector A,Vector B) {return Vector(A.x+B.x,A.y+B.y);} 14 inline Vector operator * (Vector A,double p) {return Vector(A.x*p,A.y*p);} 15 inline double Slope(Vector A) {if (fabs(A.x)<eps) return Inf; return A.y/A.x;} 16 inline double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} 17 inline double Area2(Vector A,Vector B,Vector C) {return Cross(B-A,C-A);} 18 inline Vector GetLineInsersection(Vector P,Vector v,Vector Q,Vector w) 19 { 20 Vector u=P-Q; 21 double t=Cross(w,u)/Cross(v,w); 22 return P+v*t; 23 } 24 25 int main() 26 { 27 //freopen("c.in","r",stdin); 28 scanf("%d",&n); int nn=n; 29 puts("INTERSECTING LINES OUTPUT"); 30 for (int i=1;i<=nn;i++) 31 { 32 scanf("%lf%lf",&x,&y); 33 P[1]=Vector(x,y); 34 scanf("%lf%lf",&x,&y); 35 P[2]=Vector(x,y); 36 scanf("%lf%lf",&x,&y); 37 Q[1]=Vector(x,y); 38 scanf("%lf%lf",&x,&y); 39 Q[2]=Vector(x,y); 40 if (fabs(Slope(P[2]-P[1])-Slope(Q[2]-Q[1]))<eps) 41 { 42 if (fabs(Area2(P[2],P[1],Q[1]))<eps) 43 puts("LINE"); else puts("NONE"); 44 continue; 45 } 46 Vector W=GetLineInsersection(P[1],P[2]-P[1],Q[1],Q[2]-Q[1]); 47 printf("POINT %.2f %.2f\n",W.x,W.y); 48 } 49 puts("END OF OUTPUT"); 50 return 0; 51 }
POJ 3304 判断是否有一条直线经过所有线段
就是枚举不同线段的两个端点。
1 #include <cstdio> 2 #include <cmath> 3 const double eps=1e-8; 4 int KASE,n; 5 bool flag; 6 struct Vector 7 { 8 double x,y; 9 Vector (double x=0,double y=0):x(x),y(y){} 10 }a[110],b[110]; 11 inline Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x,A.y-B.y);} 12 inline double Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} 13 inline double Area2(Vector A,Vector B,Vector C) {return Cross(B-A,C-A);} 14 inline bool Check(Vector A,Vector B) 15 { 16 if (fabs(A.x-B.x)<eps && fabs(A.y-B.y)<eps) return false; 17 for (int i=1;i<=n;i++) 18 if (Area2(a[i],A,B)*Area2(b[i],A,B)>eps) return false; 19 return true; 20 } 21 int main() 22 { 23 scanf("%d",&KASE); 24 for (int kase=1;kase<=KASE;kase++) 25 { 26 scanf("%d",&n); 27 for (int i=1;i<=n;i++) 28 scanf("%lf%lf%lf%lf",&a[i].x,&a[i].y,&b[i].x,&b[i].y); 29 flag=false; 30 if (n<3) flag=true; 31 for (int i=1;i<=n && !flag;i++) 32 for (int j=i+1;j<=n && !flag;j++) 33 { 34 if (Check(a[i],a[j])) flag=true; 35 if (Check(a[i],b[j])) flag=true; 36 if (Check(b[i],a[j])) flag=true; 37 if (Check(b[i],b[j])) flag=true; 38 } 39 if (flag) puts("Yes!"); else puts("No!"); 40 } 41 return 0; 42 }
POJ 2318/2398 就每个端点在的区域
一个点在它左边的线段的叉积和它右边线段的叉积的符号相反,二分答案即可
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 const int Maxn=10000; 6 int n,m,C[Maxn],x1,x2,y1,y2; 7 int x,y,u,v; 8 struct Vector 9 { 10 int x,y; 11 Vector(int x=0,int y=0):x(x),y(y){} 12 }V[Maxn][2],P; 13 inline Vector operator - (Vector A,Vector B) {return Vector(A.x-B.x,A.y-B.y);} 14 inline int Cross(Vector A,Vector B) {return A.x*B.y-A.y*B.x;} 15 inline int Area2(Vector A,Vector B,Vector C) {return Cross(B-A,C-A);} 16 inline int Find(Vector P) 17 { 18 int l=0,r=n,ans; 19 // for (int i=0;i<n;i++) 20 // if (Area2(P,V[i+1][0],V[i+1][1])>0 && Area2(P,V[i][0],V[i+1][1])<0) return i; 21 while (true) 22 { 23 int mid=(l+r)>>1; 24 if (Area2(P,V[mid][0],V[mid][1])>0) r=mid; 25 else l=mid; 26 if (l+1==r) break; 27 } 28 return l; 29 cout << P.x << " " << P.y << endl;; 30 for (int i=0;i<=n;i++) 31 cout << Area2(P,V[i][1],V[i][0]) << " "; 32 cout << endl; 33 return 0; 34 // for (int i=l;i<=r;i++) 35 // if (Area2(P,V[i+1][0],V[i+1][1])>0 && Area2(P,V[i][0],V[i][1])<0) return i; 36 } 37 int main() 38 { 39 // freopen("c.in","r",stdin); 40 // freopen(") 41 while (scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2)!=EOF) 42 { 43 if (n==0) break; 44 for (int i=1;i<=n;i++) 45 { 46 scanf("%d%d",&u,&v); 47 V[i][0]=Vector(v,y2); V[i][1]=Vector(u,y1); 48 } 49 V[0][0]=Vector(x1,y2); V[0][1]=Vector(x1,y1); 50 V[++n][0]=Vector(x2,y2); V[n][1]=Vector(x2,y1); 51 memset(C,0,sizeof(C)); 52 for (int i=1;i<=m;i++) 53 { 54 scanf("%d%d",&x,&y); 55 P=Vector(x,y); 56 C[Find(P)]++; 57 } 58 for(int i=0;i<n;i++) 59 printf("%d: %d\n",i,C[i]); 60 printf("\n"); 61 } 62 return 0; 63 }
标签:
原文地址:http://www.cnblogs.com/yyjxx2010xyu/p/5479612.html