zoukankan      html  css  js  c++  java
  • SGU 106 The equation【扩展欧几里得】

    先放一张搞笑图。。
    这里写图片描述
    我一直wa2,这位不认识的大神一直wa9。。。这样搞笑的局面持续了一个晚上。。。最后各wa了10发才A。。。


    题目链接:

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=111527#problem/X

    题意:

    给定不定方程,问在给定x,y范围内的解有多少个?

    分析:

    很明显的扩欧。
    但是这题要进行特判。。

    • a,b,c小于0.
    • a,b,c等于0

    特判之后正常扩欧就好。。
    问题是我们怎样获得给定区间的解的个数。
    通解可以写成:
    x=x0+kb/gcd
    y=y0ka/gcd
    我们可以将这两个方程看成关于x0y0的两个一次函数。
    把他们放在同一坐标下,看给定函数值范围内,横坐标为整数的个数就好了。。
    向上取整和向下取整处理一下。。
    然后从这里开始无限的wa。。。后来看了题解才知道哪里错了。。

    1. 精度问题,floor和ceil函数参数要用double
    2. 可以自己实现一个floor和ceil函数,无需将参数全部转化为double。【注意负数的处理】

    代码:

    #include<iostream>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    ll extgcd(ll a, ll b, ll &x, ll &y)
    {
        ll d = a;
        if(b != 0){
            d = extgcd(b, a % b, y, x);
            y -= (a / b) * x;
        }else{
            x = 1, y = 0;
        }
        return d;
    }
    ll upper(ll a, ll b)
    {
        if(a <= 0) return a / b;
        return (a - 1) / b + 1;
    }
    ll lower(ll a, ll b)
    {
        if(a >= 0) return a / b;
        return (a + 1) / b - 1;
    }
    int main (void)
    {
        ll a, b, c,x1, x2, y1,y2;
        cin>>a>>b>>c>>x1>>x2>>y1>>y2;
        if(c < 0) c = -c;
        else { a = -a; b= -b;}
        if(a < 0){a = -a; x1 = -x1; x2 = -x2; swap(x1, x2);}
        if(b < 0){b = -b; y1 = -y1; y2 = -y2; swap(y1, y2);}
        if(a * b == 0){
            if(b){
                ll yy = c / b;
                if(c % b == 0 && yy >= y1 && yy <= y2) cout<<x2 - x1 + 1<<endl;
                else cout<<0<<endl;
            }else if(a){
                ll xx = c / a;
                if(c % a == 0 && xx >= x1 && xx <= x2) cout<<y2 - y1 + 1<<endl;
                else cout<<0<<endl;
            }else {
                if(c != 0) cout<<0<<endl;
                else cout<<(x2 - x1 + 1) * (y2 - y1 + 1)<<endl;
            }
            return 0;
        }
        ll x0, y0;
        ll gcd = extgcd(a, b, x0, y0);
        x0 *= c;
        y0 *= c;
        if(c % gcd != 0) return cout<<0<<endl, 0;
        a /= gcd;
        b /= gcd;
        c /= gcd;
    
        long long bb = min (lower(x2 - x0, b), lower(y0 - y1, a));
        long long aa = max (upper(x1 - x0, b), upper(y0 - y2, a));
        if (bb < aa) cout<<0<<endl;
        else cout<< bb - aa + 1<<endl;
    
        return 0;
    }
  • 相关阅读:
    grep命令详解;单引号和双引号区别(转载)
    Linux下的系统性能调优工具--Perf (转载)
    Shiro
    WebLogic和Tomcat
    MD5加密(java和c#)
    深入理解java泛型
    VS2015常用快捷键总结(转)
    Java 反射 使用总结
    @RequestParam与@PathVariable的区别
    SVN被锁定的几种解决方法
  • 原文地址:https://www.cnblogs.com/Tuesdayzz/p/5758662.html
Copyright © 2011-2022 走看看