[SGU]106. The Equation

Analysis

    使用扩展欧几里德算法……其实是第一次听说这算法,百度了一下才有了思路……程序里有几个是否非零的判断。

Accepted Code

var
    x1,x2,x,y1,y2,y,a,b,c,d,tmp:int64;
    up,down,temp:extended;

function extended_gcd(a,b:int64;var x,y:int64):int64;
begin
    if b=0 then
    begin
        x:=1;
        y:=0;
        extended_gcd:=a;
        exit;
    end;
    extended_gcd:=extended_gcd(b,a mod b,y,x);
    y:=y-a div b*x;
end;

begin
    readln(a,b,c,x1,x2,y1,y2);
    c:=-c;
    if c<0 then
    begin
        a:=-a;
        b:=-b;
        c:=-c;
    end;
    if a<0 then
    begin
        a:=-a;
        x1:=-x1;
        x2:=-x2;
        tmp:=x1;
        x1:=x2;
        x2:=tmp;
    end;
    if b<0 then
    begin
        b:=-b;
        y1:=-y1;
        y2:=-y2;
        tmp:=y1;
        y1:=y2;
        y2:=tmp;
    end;
    if (a=0) and (b=0) then
    begin
        if c=0 then
            writeln((x2-x1+1)*(y2-y1+1))
        else
            writeln(0);
        exit;
    end;
    if a=0 then
    begin
        if (c mod b=0) and (c div b>=y1) and (c div b<=y2) then
            writeln(x2-x1+1)
        else
            writeln(0);
    end
    else
        if b=0 then
        begin
            if (c mod a=0) and (c div a>=x1) and (c div a<=x2) then
                writeln(y2-y1+1)
            else
                writeln(0);
        end
        else
        begin
            d:=extended_gcd(a,b,x,y);
            if c mod d<>0 then
                writeln(0)
            else
            begin
                a:=a div d;
                b:=b div d;
                c:=c div d;
                down:=(x1-c*x)/b; 
                up:=(x2-c*x)/b;
                temp:=(c*y-y2)/a;
                if temp>down then
                    down:=temp;
                temp:=(c*y-y1)/a;
                if temp<up then
                    up:=temp;
                if up<down then
                    writeln(0)
                else
                begin
                    x1:=trunc(down);
                    if x1<down then
                        inc(x1);
                    x2:=trunc(up);
                    if x2>up then
                        dec(x2);
                    writeln(x2-x1+1);
                end;
            end;
        end;
end.



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值