zoukankan      html  css  js  c++  java
  • LightOJ 1306

    题意:http://www.lightoj.com/volume_showproblem.php?problem=1306

    在范围内 求出满足ax+b*y+c=0的解    典型的扩展欧几里得

    首先我们可以求出ax+by=gcd(a,b)=g的一个组解(x0,y0).而要使ax+by=c有解,必须有c%g==0.

    继而可以得到ax+by=c的一个组解x1=c*x0/g , y1=c*y0/g

    这样可以得到ax+by=c的通解为:

                      x=x1+b*t;//为了范围更大这里的 b=b/g;   a=a/g

                      y=y1-a*t;

    表达式为 x=x0*c/g+b*t/g

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<map>
    #include<vector>
    #include<math.h>
    #include<string>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LL long long
    #define N 10006
    #define Lson rood<<1
    #define Rson rood<<1|1
    LL exgcd(LL a,LL b,LL &x,LL &y)///扩展欧几里得 算出ax+by=gcd(a,b)的一组解
    {
        if(b==0) {
            x=1;y=0;
            return a;
        }
        else {
            LL g=exgcd(b,a%b,x,y);
            LL t=x;
            x=y;
            y=t-a/b*y;
            return g;
        }
    }
    LL sign(LL a)
    {
        if(a==0) return 0;
        return a>0?1:-1;
    }
    LL ceil(LL a,LL b)
    {
        LL s=sign(a)*sign(b);
        return b/a+(b%a!=0&&s>0);
    }
    LL floor(LL a,LL b)
    {
        LL s=sign(a)*sign(b);
        return b/a-(b%a!=0&&s<0);
    }
    int main()
    {
        int T,t=1;
        scanf("%d",&T);
        while(T--)
        {
            LL a,b,c,x1,x2,y1,y2;
            scanf("%lld %lld %lld %lld %lld %lld %lld,",&a,&b,&c,&x1,&x2,&y1,&y2);
            printf("Case %d: ",t++);
            if(!a&&!b)///三个特判  a与b为0 的处理
            {
                if(c) printf("0
    ");
                else printf("%lld
    ",(x2-x1+1)*(y2-y1+1));
                continue;
            }
            else if(!a)
            {
                if(c%b) printf("0
    ");
                else if((-c/b)>=y1&&(-c/b)<=y2) printf("%lld
    ",x2-x1+1);
                else printf("0
    ");
                continue;
            }
            else if(!b)
            {
                if(c%a) printf("0
    ");
                else if((-c/a)>=x1&&(-c/a)<=x2) printf("%lld
    ",y2-y1+1);
                else printf("0
    ");
                continue;
            }   
            LL x,y;
            LL g=exgcd(a,b,x,y);
            if(c%g!=0){///求出一组解 判断是否有解
                printf("0
    ");
                continue;
            }///因为是一元一次方程  需要看清是递增还是递减  然后在处理
            if(sign(g)*sign(b)<0) swap(x1,x2);
            LL k1=ceil(b,g*x1+c*x);//因为是小值 有部分已经占用 需要向上取整 
            LL k2=floor(b,g*x2+c*x);//同理 向下取整
            if(sign(-a)*sign(g)<0) swap(y1,y2);
            LL k3=ceil(-a,g*y1+c*y);
            LL k4=floor(-a,g*y2+c*y);
            k1=max(k1,k3);
            k2=min(k2,k4);
            if(k1>k2) printf("0
    ");
            else printf("%lld
    ",k2-k1+1);
        }
        return 0;
    }
  • 相关阅读:
    ClickHouse
    SparkSql运行原理详细解析
    Hive优化一
    低代码平台,到底能给企业带来什么?
    观点:BPM已经过时了?
    一个好产品,只是帮用户做好了一件事
    高科技电子行业的信息化怎么做?
    【重要!】告K2老客户书
    移动互联网公司如何将BPM流程管理变身移动化?
    BPM业务流程管理与SAP如何更好集成整合?
  • 原文地址:https://www.cnblogs.com/a719525932/p/7691723.html
Copyright © 2011-2022 走看看