Online Judge | Problem Set | Authors | Online Contests | User | ||||||
---|---|---|---|---|---|---|---|---|---|---|
Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest |
调试了一下午 纪念一下/* 凸多边形的宽 多边形内最长线段 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<vector> #include <ctime> #include<queue> #include<set> #include<map> #include<stack> #include<cmath> #define mst(ss,b) memset((ss),(b),sizeof(ss)) #define maxn 0x3f3f3f3f ///#pragma comment(linker, "/STACK:102400000,102400000") using namespace std; struct point { double x,y; point(double x=0,double y=0):x(x),y(y) {} }; const double eps=1e-8; const double pi=acos(-1.0); typedef point vec; vec operator + (point a,point b) { return vec(a.x+b.x,a.y+b.y); } vec operator - (point a,point b) { return vec(a.x-b.x,a.y-b.y); } vec operator * (point a,double t) { return vec(a.x*t,a.y*t); } vec operator / (point a,double t) { return vec(a.x/t,a.y/t); } bool operator == (const point &a,const point &b) { if(fabs(a.x-b.x)<=eps && fabs(a.y-b.y)<=eps) return true; return false; } int dcmp(double x) { if(fabs(x)<=eps) return 0; return x<0?-1:1; } bool cmp(point a,point b) { if(dcmp(a.x-b.x)==0) return a.y<b.y; return a.x<b.x; } double dot(vec a,vec b) {///点积 return a.x*b.x+a.y*b.y; } double disn(point a,point b) { return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); /*两点之间的距离*/ } double lentgh(vec a) { ///向量长度 return sqrt(dot(a,a)); } double cross(vec a,vec b) { return a.x*b.y-a.y*b.x; } void convexhull(point *s,int &n) { sort(s,s+n,cmp); int m=0; point p[110]; for(int i=0; i<n; i++) { while(m>1 && dcmp(cross(p[m-1]-p[m-2],s[i]-p[m-2]))<=0) m--; p[m++]=s[i]; } int k=m; for(int i=n-2; i>=0; i--) { while(m>k && dcmp(cross(p[m-1]-p[m-2],s[i]-p[m-2]))<=0) m--; p[m++]=s[i]; } m--; n=m; for(int i=0; i<n; i++) s[i]=p[i]; } double distancetoseg(point p,point a,point b) { if(a==b) return lentgh(p-a); vec v1=b-a; vec v2=p-a; vec v3=p-b; if(dcmp(dot(v1,v2))<0) return lentgh(v2); else if(dcmp(dot(v1,v3))>0) return lentgh(v3); else return fabs(cross(v1,v2))/lentgh(v1); /*点到线段的距离*/ } double slove(point a,point b,point c,point d) { double d1=distancetoseg(a,c,d); double d2=distancetoseg(b,c,d); double d3=distancetoseg(c,a,b); double d4=distancetoseg(d,a,b); return min(max(d1,d2),max(d3,d4)); } double rotating_cali(point *s,int n) { double ans=maxn*1.0; int l=0,r=0; for(int i=1; i<n; i++) { if(s[i].y<=s[l].y) l=i; if(s[i].y>=s[r].y) r=i; } s[n]=s[0]; for(int i=0; i<n; i++) { while(dcmp(cross(s[l+1]-s[l],s[r+1]-s[l])-cross(s[l+1]-s[l],s[r]-s[l]))>0) r=(r+1)%n; double d=slove(s[l],s[l+1],s[r],s[r+1]); ans=min(d,ans); l=(l+1)%n; } return ans; } struct line { point p; vec v; double ang; line() {} line(point p,vec v):p(p),v(v) { ang=atan2(v.y,v.x); } bool operator < (const line &l) const { return ang-l.ang<-eps; } }; point GetLineIntersection(line a,line b) { vec u=a.p-b.p; double t=cross(b.v,u)/cross(a.v,b.v); return a.p+a.v*t; /*两条直线的交点*/ } bool onseg(point p,point a1,point a2) { return dcmp(cross(a1-p,a2-p))==0 && dcmp(dot(a1-p,a2-p))<0; /*点在线段上 不包含端点(<=0)*/ } int pointinpoly(point p,point *poly,int n) { int wn=0; for(int i=0; i<n; i++) { if(onseg(p,poly[i],poly[(i+1)%n])) return 1;///点在边界上 int k=dcmp(cross(poly[(i+1)%n]-poly[i],p-poly[i])); int d1=dcmp(poly[i].y-p.y); int d2=dcmp(poly[(i+1)%n].y-p.y); if(k>0 && d1<=0 && d2>0) wn++; if(k<0 && d2<=0 && d1>0) wn--; } if(wn!=0) return 1;///内部 return 0;///外部 /*点在多边形内 p是点 poly[]是多边形 多边形的点必须是顺时针或者逆时针 n是点的个数 */ } double getd(point a,point b,point *s,int n) { s[n]=s[0]; point p[110]; int m=0; for(int i=0; i<n; i++) { if(s[i]==a || s[i+1]==b) continue; line c=line(a,b-a); line d=line(s[i],s[i+1]-s[i]); p[m++]=GetLineIntersection(c,d); } sort(p,p+m,cmp); int l=0; for(int i=0; i<m; i++) { if(p[i]==p[i+1]) continue; p[l++]=p[i]; } m=l; double d=0,sum=0; p[m]=p[0]; for(int i=0; i<m-1; i++) { point mid=(p[i]+p[i+1])/2; if(pointinpoly(mid,s,n)) { sum+=disn(p[i],p[i+1]); if(d<sum) d=sum; } else sum=0; } return d; } double getlong(point *s,int n) { s[n]=s[0]; double lon=0; int x=0,y=0; for(int i=0; i<n; i++) { for(int j=i+1; j<n; j++) { double d=getd(s[i],s[j],s,n); if(dcmp(d-lon)>0) { lon=d; x=i; y=j; } } } return lon; } double getshort(point *s,int n) { double d=maxn*1.0; for(int i=0; i<n; i++) { double tmp=0; for(int j=0; j<n; j++) { double tm=max(tmp,distancetoseg(s[j],s[i],s[i+1])); if(tmp<tm) tmp=tm; } d=min(d,tmp); } return d; } point s[110],p[110]; int main() { int T,n,m; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%lf%lf",&s[i].x,&s[i].y); double lon=getlong(s,n); scanf("%d",&m); for(int i=0; i<m; i++) scanf("%lf%lf",&p[i].x,&p[i].y); convexhull(p,m); p[m]=p[0]; double coin=rotating_cali(p,m); ///double coin=getshort(p,m); ///printf("%.2f %.2f\n",coin,lon); if(dcmp(lon-coin)>=0) printf("legal\n"); else printf("illegal\n"); } return 0; } /* 1000 7 0 0 3 0 1 1 2 2 1 2 3 3 0 3 1 0 0 */ Followed by: Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator