2020ICPC上海 L-Traveling in the Grid World
阿新 • • 發佈:2020-12-15
2020ICPC上海 L-Traveling in the Grid World
題意
給定一個\(n\times m\)的網格圖,你站在起始點\((0,0)\),每次移動可以選擇一個點\((x,y)\)走線段到達它且這條線段不能經過其他格點,可以做任意次移動,問到達\((n,m)\)所需的移動距離總和最小為多少。
分析
一個簡單的結論:若\(gcd(n,m)=1\),可以直接從\((0,0)\)走到\((n,m)\),否則只需要一次轉折即可到達\((n,m)\)。假設轉折點為\((x,y)\)那麼需要滿足\(gcd(x,y)=1\)且\(gcd(n-x,m-y)=1\)。暴力列舉\((0,0)\)和\((n,m)\)
Code
#include<bits/stdc++.h> using namespace std; const double eps=1e-8; const int mod=1e9+7; const int N=1e5+10; const int inf=1e9; int T,n,m; int xx[]={1,-1,0,0}; int yy[]={0,0,1,-1}; double cal(int x,int y){ return sqrt(1.0*x*x+1.0*y*y); } double gao(int x,int y){ if(y<0||y>m) return inf; if(__gcd(x,y)!=1||__gcd(n-x,m-y)!=1) return inf; if(x*m==y*n) return inf; return cal(x,y)+cal(n-x,m-y); } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); double ans=inf; if(__gcd(n,m)==1){ ans=sqrt(1.0*n*n+1.0*m*m); }else{ for(int i=0;i<=n;i++){ int j=i*m/n; ans=min(ans,gao(i,j)); ans=min(ans,gao(i,j-1)); ans=min(ans,gao(i,j+1)); } } printf("%.9f\n",ans); } return 0; }