口胡五分钟,代码两小时!
这个题啊,真是好写,也不好写。
好写呢,在于建个图,再跑一遍,比较最小值,就没了
不好写呢,就在于:
1.每个矩形只给了3个点.....
2.代码长(可能不是),相近的变量多(这是我)等等
来一步一步分析吧。。。
题意:
(略)
建图
找到矩形的另外
个点
这个东西咋找呢?用亿点初中几何知识知道矩形是平行四边形,而平行四边形是对角线互相平分的。
如图所示:
其中,点为输入的点,
是所求的点,对角线交点为
这个例子中,是一条对角线,
是另一条。根据中点公式,可以得到
所以可得
于是, 我们再用勾股定理判断一下哪两个点构成对角线,然后就能求出这个点啦!
建图
这里我们发现题目给了两种路线,一种是城市之间的航空路线,一种是城市内部的公路。
所以建图的主要问题就在于判断两个点是否在同一城市内。
这个问题,要靠你标点的方式确定,此处就举本人的例子来说明。
我的想法是第个城市标号
,第
个城市标号
,以此类推。
那么这些点的标号与对应的城市号有什么关系呢?
经过研究发现,若点的编号为,则它对应的城市编号即为
(下取整)
于是这样就行了。
最短路
,一看数据范围,
所以最多只有个点,
都能过。
那么的最短路是啥?
啊~
跑一遍,然后求一下
的每个机场到
的每个机场的最小值就过了~
完整代码:
#include<bits/stdc++.h> using namespace std; #define ll long long #define f(i,a,b) for(int i=a;i<=b;i++) const ll inf=0x7f7f7f7f; ll s,A,B,TTT; double ans=inf,t,dis[410][410]; double x[410],y[410],T[110]; double diss(double x1,double y1,double x2,double y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));} double ds(double x1,double y1,double x2,double y2){return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);} int main() { scanf("%lld",&TTT); while(TTT--){ memset(dis,0,sizeof(dis)),ans=inf; scanf("%lld%lf%lld%lld",&s,&t,&A,&B); f(i,1,s){ scanf("%lf%lf%lf%lf%lf%lf%lf",&x[(i-1)*4+1],&y[(i-1)*4+1],&x[(i-1)*4+2],&y[(i-1)*4+2],&x[(i-1)*4+3],&y[(i-1)*4+3],&T[i]); double dab=ds(x[(i-1)*4+1],y[(i-1)*4+1],x[(i-1)*4+2],y[(i-1)*4+2]); double dac=ds(x[(i-1)*4+1],y[(i-1)*4+1],x[(i-1)*4+3],y[(i-1)*4+3]); double dbc=ds(x[(i-1)*4+2],y[(i-1)*4+2],x[(i-1)*4+3],y[(i-1)*4+3]); if(dab+dac==dbc)x[i*4]=x[(i-1)*4+2]+x[(i-1)*4+3]-x[(i-1)*4+1],y[i*4]=y[(i-1)*4+2]+y[(i-1)*4+3]-y[(i-1)*4+1];else if(dab+dbc==dac)x[i*4]=x[(i-1)*4+1]+x[(i-1)*4+3]-x[(i-1)*4+2],y[i*4]=y[(i-1)*4+1]+y[(i-1)*4+3]-y[(i-1)*4+2];else if(dbc+dac==dab)x[i*4]=x[(i-1)*4+2]+x[(i-1)*4+1]-x[(i-1)*4+3],y[i*4]=y[(i-1)*4+2]+y[(i-1)*4+1]-y[(i-1)*4+3]; } f(i,1,s*4)f(j,1,s*4)if(i!=j){ if((i-1)/4!=(j-1)/4)dis[i][j]=t*diss(x[i],y[i],x[j],y[j]); else dis[i][j]=T[(i-1)/4+1]*diss(x[i],y[i],x[j],y[j]); } f(k,1,s*4)f(i,1,s*4)f(j,1,s*4)dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]); f(i,1,4)f(j,1,4)ans=min(ans,dis[(A-1)*4+i][(B-1)*4+j]); printf("%.1lf\n",ans); } return 0; }