wf 2017A

给一个多边形,问能放进去的最长的线段的长度。

我调了两个小时结果加了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\n",ans);
 98 }
 99 /**
100 5
101 2 0
102 2 3
103 1 1
104 0 2
105 0 0
106  */
View Code

猜你喜欢

转载自www.cnblogs.com/MXang/p/10604535.html