zoukankan      html  css  js  c++  java
  • UVA 11768 Lattice Point or Not(扩展欧几里德)

    将直线转化为ax + by = c的形式,然后扩展欧几里得求在[x1, x2]之间的解

    对直线与坐标轴平行的特判

    调试了好长时间,注意:

    1 正负数转化为整型的处理

    2 注意判断有无解

    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<vector>
    #include<cmath>
    #include<utility>
    using namespace std;
    typedef long long LL;
    const int N = 1008, INF = 0x3F3F3F3F;
    const double eps = 1e-6, meps = 1e-7;
    LL Ext_gcd(LL a,LL b,LL &x,LL &y){//扩展欧几里得
       if(b==0) { x=1, y=0; return a; }
       LL ret= Ext_gcd(b,a%b,y,x);
       y-= a/b*x;
       return ret;
    }
    
    LL gcd(LL a, LL b){
    	while(b){
    		LL t = a % b;
    		a = b;
    		b = t;
    	}
    	return a;
    }
    
    
    LL  cal(LL x1, LL x2, LL x, LL mod){
        if(x1 > x2){
            return 0;
        }
        if(x >= x1 && x <= x2){
            return (x - x1) / mod + 1 + (x2 - x) / mod;
        }
        if(x < x1){
            return (x2 - x) / mod - (x1 - 1 - x) / mod;
        }
        return (x - x1) / mod - (x - x2 - 1) / mod;
    
    }
    LL toLL(double x){
        if(x > 0){
            return x + eps;
        }
        if(x < 0){
            return x - eps;
        }
        return 0;
    }
    int main(){
        double t1, t2, t3, t4;
        int t;
        scanf("%d", &t);
        while(t--){
        	scanf("%lf %lf %lf %lf", &t1, &t2, &t3, &t4);
        	if(abs(t1 - t3) < eps){
                if(abs(t1 - (LL)t1) < eps){
                    double t22 = min(t2, t4);
                    double t44 = max(t2, t4);
                    printf("%lld
    ", cal((LL)ceil(t22), (LL)floor(t44), (LL)ceil(t22), 1));
                }else{
                    printf("0
    ");
                }
                continue;
        	}
    
            if(abs(t2 - t4) < eps){
                if(abs(t2 - (LL)t2) < eps){
                    double t11 = min(t1, t3);
                    double t33 = max(t1, t3);
                    printf("%lld
    ", cal((LL)ceil(t11), (LL)floor(t33), (LL)ceil(t11), 1));
                }else{
                    printf("0
    ");
                }
                continue;
        	}
    
        	LL x1 = toLL(t1 * 10), y1 = toLL(t2 * 10), x2 = toLL(t3 * 10), y2 = toLL(t4 * 10);
    
        	//cout<<x1<<" "<<y1<<"  "<<x2<<"  "<<y2<<"
    ";
    
            if(x1 > x2){
                swap(x1, x2);
                swap(y1, y2);
            }
            LL a = (y2 - y1) * 10, b = (x1 - x2) * 10;
            LL c = x1 * y2 - x2 * y1;
            LL gc = gcd(gcd(a, b), c);
            a /= gc;
            b /= gc;
            c /= gc;
    
            //cout<<a<<"  "<<b<<"  "<<c<<"  ***
    ";
            if(c % gcd(a, b)){
                printf("0
    ");
                continue;
            }
    
            //cout<<a * t1 + b * t2 - c<<" aa
    ";
            //cout<<a * t3 + b * t4 - c<<" aa
    ";
            LL x, y;
            Ext_gcd(a, b, x, y);
            //cout<<x<<"  "<<y<<" xy
    ";
            x = c / gcd(a, b) * x;
            //cout<<x<<"  spe
    ";
            if(t1 > t3){
                swap(t1, t3);
            }
            printf("%lld
    ",cal((LL)ceil(t1), (LL)floor(t3), x, abs(b / gcd(a, b))));
            //cout<<tp<<"  cal
    ";
        }
    
        return 0;
    }
    

      

  • 相关阅读:
    第一节 49_ref_out 简单
    第一节 38函数 简单
    第二节 2面向对像简介 简单
    第一节 42字符串基础 简单
    第二节 3属性 简单
    第一节 33enum枚举 简单
    Java jdbc 数据库
    css 使IE和FIREFOX下变为手型
    JS调用PageMethods
    USB设备量产导致通用串行总线控制器显示感叹号解决办法
  • 原文地址:https://www.cnblogs.com/IMGavin/p/6035679.html
Copyright © 2011-2022 走看看