首页 > 代码库 > JLOI金属切割

JLOI金属切割

JLOI金属切割

技术分享

时间限制:

1000

空间限制:

512000
xjb乱搞的码农题.
对切边的顺序搞全排列.
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cmath>
  5 using namespace std;
  6 const int N=15;
  7 long double c[N],a[N],b[N],x[N],y[N],K[N],B[N],ans=1e20,n,m;
  8 int w,ord[N];
  9 bool used[N],upst[N];
 10 inline void calline(int t)
 11 {
 12     if(x[t]==x[t+1]) upst[t]=1;
 13     else
 14     {
 15         K[t]=(y[t]-y[t+1])/(x[t]-x[t+1]);
 16         B[t]=y[t]-K[t]*x[t];
 17         a[t]=y[t]-y[t+1];
 18         b[t]=x[t+1]-x[t];
 19         c[t]=x[t]*y[t+1]-x[t+1]*y[t];
 20         upst[t]=0;
 21     }
 22 }
 23 inline void getmin()
 24 {
 25     long double Xl,Xr,x1,x2,xx,X,res=0;
 26     for(int i=1;i<=w;i++)
 27     {
 28         if(upst[ord[i]])
 29         {
 30             Xl=0;
 31             Xr=m;
 32             x1=y[ord[i]];
 33             x2=y[ord[i]+1];
 34             if(x1>x2) swap(x1,x2);
 35             X=x[ord[i]];
 36             for(int j=1;j<i;j++) if(!upst[ord[j]])
 37             {
 38                 xx=-(a[ord[j]]*X+c[ord[j]])/b[ord[j]];
 39                 if(xx<=x1&&xx>Xl) Xl=xx;
 40                 if(xx>=x2&&xx<Xr) Xr=xx;
 41             }
 42             res+=Xr-Xl;
 43             continue;
 44         }
 45         if(K[ord[i]]>0)
 46         {
 47             if(B[ord[i]]>=0) Xl=0;
 48             else Xl=-B[ord[i]]/K[ord[i]];
 49             if(K[ord[i]]*n+B[ord[i]]<=m) Xr=n;
 50             else Xr=(m-B[ord[i]])/K[ord[i]];
 51         }
 52         else if(K[ord[i]]<=0)
 53         {
 54             if(B[ord[i]]<=m) Xl=0;
 55             else Xl=(m-B[ord[i]])/K[ord[i]];
 56             if(K[ord[i]]*n+B[ord[i]]>=0) Xr=n;
 57             else Xr=-B[ord[i]]/K[ord[i]];
 58         }
 59         x1=x[ord[i]];
 60         x2=x[ord[i]+1];
 61         if(x1>x2) swap(x1,x2);
 62         for(int j=1;j<i;j++)
 63         {
 64             long double d=a[ord[i]]*b[ord[j]]-a[ord[j]]*b[ord[i]];
 65             if(d==0&&!upst[ord[j]]) continue;
 66             if(!upst[ord[j]]) xx=(b[ord[i]]*c[ord[j]]-b[ord[j]]*c[ord[i]])/d;
 67             else xx=x[ord[j]];
 68             if(xx<=x1&&xx>Xl) Xl=xx;
 69             if(xx>=x2&&xx<Xr) Xr=xx;
 70         }
 71         res+=(Xr-Xl)*sqrt(1+K[ord[i]]*K[ord[i]]);
 72     }
 73     ans=min(ans,res);
 74 }
 75 inline void list(int x)
 76 {
 77     if(x==w)
 78     {
 79         getmin();
 80         return;
 81     }
 82     for(int i=1;i<=w;i++) if(!used[i])
 83     {
 84         used[i]=1;
 85         ord[x+1]=i;
 86         list(x+1);
 87         used[i]=0;
 88     }
 89 }
 90 int main()
 91 {
 92     scanf("%Lf%Lf%d",&n,&m,&w);
 93     for(int i=1;i<=w;i++) scanf("%Lf%Lf",&x[i],&y[i]);
 94     x[w+1]=x[1];
 95     y[w+1]=y[1];
 96     for(int i=1;i<=w;i++) calline(i);
 97     memset(used,0,sizeof(used));
 98     list(0);
 99     printf("Minimum total length = %.3Lf\n",ans);
100     return 0;
101 }

 

JLOI金属切割