bzoj1857: [Scoi2010]傳送帶
阿新 • • 發佈:2019-02-07
看到這題第一感覺暴力呀233
然後就亂搞水過了(資料太水?)
我的做法是將AB,CD分別等分為512段
這樣AB,CD上各有513個頂點,不妨設AB上的頂點為E,CD上的頂點為F
通過數學容易得到A到D的最短時間移動路徑是AE-EF-FD,
那列舉E在AB上那513個頂點位置,列舉F在CD上那513個頂點位置,
其中滿足AE/P+FD/Q+EF/R最小的E,F點時路徑移動時間最短,此時AE/P+FD/Q+EF/R就是答案
由於線段長度有限,取512段基本可以滿足精度問題
聽神犇說這題是三分?我表示一臉懵逼2333
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<cstdlib> using namespace std; int ax,ay,bx,by,cx,cy,dx,dy; int p,q,r; int tza=0,tzb=0; double ka,kb,ba,bb; double sum=0,ans=0x3f3f3f3f; struct data{ double xi,yi; }op[2005],kp[2005]; int cnt=2,tot=2; void find(double axx,double ayy,double bxx,double byy,int timm) { if(timm>8)return ; double oxx,oyy; oxx=(axx+bxx)/2.0; oyy=(ayy+byy)/2.0; cnt++; op[cnt].xi=oxx; op[cnt].yi=oyy; find(axx,ayy,oxx,oyy,timm+1); find(oxx,oyy,bxx,byy,timm+1); } void seach(double axx,double ayy,double bxx,double byy,int timm) { if(timm>8)return ; double oxx,oyy; oxx=(axx+bxx)/2.0; oyy=(ayy+byy)/2.0; tot++; kp[tot].xi=oxx; kp[tot].yi=oyy; seach(axx,ayy,oxx,oyy,timm+1); seach(oxx,oyy,bxx,byy,timm+1); } void lcr(int x,int y) { double lena,lenb,lenc; lena=sqrt((kp[x].xi-ax)*(kp[x].xi-ax)+(kp[x].yi-ay)*(kp[x].yi-ay)); lena/=(double)p; lenb=sqrt((op[y].xi-dx)*(op[y].xi-dx)+(op[y].yi-dy)*(op[y].yi-dy)); lenb/=(double)q; lenc=sqrt((kp[x].xi-op[y].xi)*(kp[x].xi-op[y].xi)+(kp[x].yi-op[y].yi)*(kp[x].yi-op[y].yi)); lenc/=(double)r; sum=(lena+lenb+lenc); ans=min(sum,ans); } int main() { int i,j,k,l; scanf("%d%d%d%d",&ax,&ay,&bx,&by); scanf("%d%d%d%d",&cx,&cy,&dx,&dy); scanf("%d%d%d",&p,&q,&r); op[1].xi=cx;op[1].yi=cy; op[2].xi=dx;op[2].yi=dy; find(cx,cy,dx,dy,0); kp[1].xi=ax;kp[1].yi=ay; kp[2].xi=bx;kp[2].yi=by; seach(ax,ay,bx,by,0); for(i=1;i<=tot;i++){ for(j=1;j<=cnt;j++){ lcr(i,j); } } printf("%.2lf",ans); return 0; }