给一个多边形,问能放进去的最长的线段的长度。
我调了两个小时结果加了inline就过???什么东西啊。2000+MS->890MS
真实自闭啊。
dls寒假已经讲的很清楚了(别问我为什么现在才做)
就是枚举所有点对然后 求出来这条直线 与多边形所有点的 交点,然后遍历这些交点,相当于进行一个最大字段和的操作。
如何check线段是不是在内部的话取线段中点就可以
调了一晚上简直自闭了,我寻思我剪枝还比别人多,做法一样的怎么我就过不去呢??
感觉把campdiv2消化干净的话可以get到超级多的新姿势呢
1 #include <cstdio> 2 #include <algorithm> 3 #include <cmath> 4 #include <vector> 5 using namespace std; 6 typedef double db; 7 const db eps = 1e-6; 8 const db pi = acos(-1); 9 inline int sign(db k){ 10 if (k>eps) return 1; else if (k<-eps) return -1; return 0; 11 } 12 inline int cmp(db k1,db k2){return sign(k1-k2);} 13 inline int inmid(db k1,db k2,db k3){return sign(k1-k3)*sign(k2-k3)<=0;}// k3 在 [k1,k2] 内 14 struct point{ 15 db x,y; 16 point operator + (const point &k1) const{return (point){k1.x+x,k1.y+y};} 17 point operator - (const point &k1) const{return (point){x-k1.x,y-k1.y};} 18 point operator * (db k1) const{return (point){x*k1,y*k1};} 19 point operator / (db k1) const{return (point){x/k1,y/k1};} 20 int operator == (const point &k1) const{return cmp(x,k1.x)==0&&cmp(y,k1.y)==0;} 21 bool operator<(const point &k1)const { 22 int c = cmp(x,k1.x); 23 if(c)return c==-1; 24 return cmp(y,k1.y)==-1; 25 } 26 inline db abs(){ return sqrt(x*x+y*y);} 27 inline db abs2(){return x*x+y*y;} 28 inline db dis(point k1){return (*this-k1).abs();} 29 int getP() const{return sign(y)==1||(sign(y)==0&&sign(x)==-1);} 30 }; 31 inline db cross(point k1,point k2){return k1.x*k2.y-k1.y*k2.x;} 32 inline db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y;} 33 inline int inmid(point k1,point k2,point k3){return inmid(k1.x,k2.x,k3.x)&&inmid(k1.y,k2.y,k3.y);} 34 inline int onS(point k1,point k2,point q){return inmid(k1,k2,q)&&sign(cross(k1-q,k2-k1))==0;} 35 point proj(point k1,point k2,point q){ 36 point k=k2-k1;return k1+k*(dot(q-k1,k)/k.abs2()); 37 } 38 inline int checkLL(point k1,point k2,point k3,point k4){//判重合或者平行 39 return cmp(cross(k3-k1,k4-k1),cross(k3-k2,k4-k2))!=0; 40 } 41 point getLL(point k1,point k2,point k3,point k4){ 42 db w1 = cross(k1-k3,k4-k3),w2=cross(k4-k3,k2-k3); 43 return (k1*w2+k2*w1)/(w1+w2); 44 } 45 int n;point p[205]; 46 inline int contain(point q){ // 2 内部 1 边界 0 外部 47 int pd=0; 48 for (int i=1;i<=n;i++){ 49 point u=p[i-1],v=p[i]; 50 if (onS(u,v,q)) return 1; if (cmp(u.y,v.y)>0) swap(u,v); 51 if (cmp(u.y,q.y)>=0||cmp(v.y,q.y)<0) continue; 52 if (sign(cross(u-v,q-v))<0) pd^=1; 53 } 54 return pd<<1; 55 } 56 db ans=0; 57 inline void slove(point x,point y){ 58 vector<point> v; 59 for(int i=0;i<n;i++){ 60 if(sign(cross(y-x,p[i]-x)*cross(y-x,p[i+1]-x))<= 0){ 61 point v1 = y-x,v2=p[i+1]-p[i]; 62 if(sign(cross(v1,v2)) == 0){ 63 v.push_back(p[i]); 64 v.push_back(p[i+1]); 65 } 66 else v.push_back(getLL(x,y,p[i],p[i+1])); 67 } 68 } 69 sort(v.begin(),v.end()); 70 v.resize(unique(v.begin(),v.end())-v.begin()); 71 db tmp=0;int m = v.size()-1; 72 for(int i=0;i<m;i++){ 73 point mid = (v[i]+v[i+1])/2; 74 if(contain(mid)){ 75 tmp+=v[i+1].dis(v[i]); 76 }else{ 77 ans = max(ans,tmp); 78 tmp = 0; 79 if(v[i+1].dis(v[m])<=ans) 80 return; 81 } 82 } 83 ans = max(ans,tmp); 84 } 85 int main(){ 86 //freopen("secret-046.in","r",stdin); 87 scanf("%d",&n); 88 for(int i=0;i<n;i++){ 89 scanf("%lf%lf",&p[i].x,&p[i].y); 90 } 91 p[n]=p[0]; 92 for(int i=0;i<n-1;i++){ 93 for(int j=i+1;j<n;j++){ 94 slove(p[i],p[j]); 95 } 96 } 97 printf("%.9f ",ans); 98 } 99 /** 100 5 101 2 0 102 2 3 103 1 1 104 0 2 105 0 0 106 */