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;
    }
  • 相关阅读:
    SpringMVC统一异常处理
    How to convert BigDecimal to Double in spring-data-mongodb framework
    DHCP动态主机配置协议
    你所听到的技术原理、技术本质到底是什么?
    前端技术及开发模式的演进,带你了解前端技术的前世今生
    金三银四,如何征服面试官,拿到Offer
    何谓多租户模式 ?
    骄傲的技术人,技术是你的全部吗?
    自我剖析,坚持有多难?
    从官方文档去学习之FreeMarker
  • 原文地址:https://www.cnblogs.com/a719525932/p/7691723.html
Copyright © 2011-2022 走看看