题解 P9720【[EC Final 2022] Map】
[EC Final 2022] Map
看着挺吓人的一道计算几何,其实写起来挺简单(?
首先最优的方案一定是先进行若干次连续的
为什么呢?假设在走了一段路之后再进行
所以只需要枚举
接下来重点在于如何优雅地实现
设当前坐标在
具体变换可以用点乘实现,可以参考代码。
时间复杂度
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef long double ld;
using namespace std;
const int N=110,M=10010,INF=0x3f3f3f3f;
const ld inf=2e18;
inline int max(int x,int y){return x>y?x:y;}
inline int min(int x,int y){return x<y?x:y;}
inline void swap(int &x,int &y){x^=y^=x^=y;}
struct node{
ld x,y;
node(ld xx=0,ld yy=0){x=xx,y=yy;}
void in(){scanf("%Lf%Lf",&x,&y);}
}A[5],B[5],S,T;
node operator +(node a,node b){return node(a.x+b.x,a.y+b.y);}
node operator -(node a,node b){return node(a.x-b.x,a.y-b.y);}
ld operator *(node a,node b){return a.x*b.x+a.y*b.y;}
ld operator ^(node a,node b){return a.x*b.y-a.y*b.x;}
node operator *(ld x,node a){return node(x*a.x,x*a.y);}
ld sqr(ld x){return x*x;}
ld dis(node a,node b){return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));}
int _,n,k;
ld ans;
node f(node p){
node ao=A[1],ai=A[4]-A[1],aj=A[2]-A[1];
node bo=B[1],bi=B[4]-B[1],bj=B[2]-B[1];
p=node(((p-ao)*ai)/(ai*ai),((p-ao)*aj)/(aj*aj));
return bo+p.x*bi+p.y*bj;
}
void solve(){
ans=inf;
for(int i=1;i<=4;i++)A[i].in();
for(int i=1;i<=4;i++)B[i].in();
S.in();T.in();
scanf("%d%d",&k,&n);
node u=S;
for(int i=0;i<=n;i++,u=f(u)){
node v=T;
for(int j=0;i+j<=n;j++,v=f(v))
ans=std::min(ans,dis(u,v)+k*(i+j));
}
printf("%.10Lf\n",ans);
}
int main(){
scanf("%d",&_);
while(_--)solve();
return 0;
}