• gym102900L Traveling in the Grid World (2020 ICPC Shanghai Site)


    题意

    平面上有((0,0))((n,m))总共((n+1)*(m+1))个格点。任取两点((x,y),(x',y'))连成线段,若线段上没有其他格点,则称这条线段为一条合法边。求((0,0))((n,m))的最短路径,要求相邻两条边的斜率不能相等。

    推导

    首先考虑线段上有其他格点的情况,由于两边之和大于第三边,线段数为(k)的路径一定比线段数为(k-1)的路径长。然后,对于边数为2的路径ABC,若AB上存在格点D,则路径ADC一定小于路径ABC。所以最终线段ABC上一定无格点。所以对于(n,m)不互质的情况,最短路径边数一定为2。

    对于边数为2的所有路径ABC,若存在点D在三角形ABC内部,则路径ADC一定小于路径A-B-C。所以对于每个横坐标(i),取最接近线段((0,0)-(n,m))的两个(j)作为中间点进行比较即可。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    using ll=long long;
    const int maxn=1e5+5;
    
    double dist(ll n,ll m){
        return sqrt(n*n+m*m);
    }
    
    void solve(){
        ll n,m;
        scanf("%lld%lld",&n,&m);
        if(__gcd(n,m)==1)
            printf("%.15lf
    ",dist(n,m));
        else
        {
            double ans=n+m;
            for(ll i=0;i<=n;i++)
            {
                ll j1=m*i/n,j2=j1+1;
                if(i*m==j1*n)j1--;
                j1=max(j1,0ll);
                j2=min(j2,m);
                
                if((j1-0)*(n-i)!=(m-j1)*(i-0) && __gcd(i,j1)==1 && __gcd(n-i,m-j1)==1)
                    ans=min(ans,dist(i,j1)+dist(n-i,m-j1));
                
                 if((j2-0)*(n-i)!=(m-j2)*(i-0) && __gcd(i,j2)==1 && __gcd(n-i,m-j2)==1)
                    ans=min(ans,dist(i,j2)+dist(n-i,m-j2));
            }
            printf("%.15lf
    ",ans);
        }
    }
    
    int main()
    {
        // ios::sync_with_stdio(false);
        int t=1;
        scanf("%d",&t);
        while(t--)
            solve();
    
        return 0;
    }
    
  • 相关阅读:
    Silverlight不能调试问题(转摘) Unable to start debugging. Cannot locate Microsoft Internet Explorer.
    Mac OS X 同 Windows 的概念,词汇,热键对比随录,让你更好地过度到Mac OS X
    敏捷度和成熟度
    有什么是安全的吗?
    linux定时任务的设置
    javascript闭包
    (转)JavaScript世界的一等公民 函数
    PHP魔法函数(转)
    JS字符串截取,按字节截取
    linux cp命令
  • 原文地址:https://www.cnblogs.com/intmian/p/14161560.html
Copyright © 2020-2023  润新知