zoukankan      html  css  js  c++  java
  • 2020ICPC上海 L-Traveling in the Grid World

    2020ICPC上海 L-Traveling in the Grid World

    题意

    给定一个(n imes 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
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    MFC绘图机制(二)-双缓存
    C89:论数组/指针/引用
    C89:论预处理命令
    图像优化大坑
    MFC 对话框和属性表
    jQuery-plugin-pagePiling
    jquery-ui-chosen
    JavaScript DOM编程艺术小笔记
    微信公众号素材
    iOS沙箱传值
  • 原文地址:https://www.cnblogs.com/xyq0220/p/14140623.html
Copyright © 2011-2022 走看看