Hướng dẫn giải của VM 08 Bài 05 - Số nguyên


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của flashmt

const fi='';
      fo='';
type int64=longint;
var a,b,c,d,x,y:int64;

procedure rf;
begin
     assign(input,fi);
     reset(input);
     read(a,c,b,d);
     close(input);
end;

function getmax(a,b:int64):int64;
begin
     if a>b then getmax:=a else getmax:=b;
end;

function gcd(m,n:int64):int64;
begin
     m:=abs(m); n:=abs(n);
     repeat
           if m>n then m:=m mod n
           else n:=n mod m;
     until m*n=0;
     gcd:=m+n;
end;

procedure swap(var a,b:int64);
var t:int64;
begin
     t:=a; a:=b; b:=t;
end;

procedure findroot(a,b:int64;var x0,y0:int64);
var r,q,xt,yt,x1,y1:int64;
begin
     x0:=1; y0:=0;
     x1:=0; y1:=1;
     repeat
           q:=a div b;
           r:=a mod b;
           a:=b; b:=r;
           xt:=x0; yt:=y0;
           x0:=x1; y0:=y1;
           x1:=xt-q*x1; y1:=yt-q*y1;
     until b=0;
end;

procedure pr;
var x0,y0,min,max,min1,max1:int64;
begin
     c:=d-c;
     if a=0 then
     begin
          x:=0;
          y:=c div (-b);
          exit;
     end;
     if b=0 then
     begin
          y:=0;
          x:=c div a;
          exit;
     end;
     d:=gcd(a,b);
     a:=a div d;
     b:=b div d;
     c:=c div d;
     findroot(a,b,x0,y0);
     x0:=x0*c; y0:=y0*c;
     if a*x0-b*y0<>c then
     begin
          if a*x0-b*(-y0)=c then y0:=-y0;
          if a*(-x0)-b*y0=c then x0:=-x0;
          if a*(-x0)-b*(-y0)=c then
          begin
               x0:=-x0;
               y0:=-y0;
          end;
     end;
     if (x0>=0) and (y0>=0) then
     begin
          max:=x0 div b;
          max1:=y0 div a;
          max:=getmax(max,max1);
          x0:=x0-max*b;
          y0:=y0-max*a;
     end;
     if (x0<0) and (y0<0) then
     begin
          max:=abs(x0) div b;
          max1:=abs(y0) div a;
          max:=getmax(max,max1);
          x0:=x0+max*b;
          y0:=y0+max*a;
     end;
     if (x0>=0) and (y0<0) then
     begin
          max:=abs(y0) div a;
          x0:=x0+max*b;
          y0:=y0+max*a;
     end;
     if (x0<0) and (y0>=0) then
     begin
          max:=abs(x0) div b;
          x0:=x0+max*b;
          y0:=y0+max*a;
     end;
     if (x0<0) or (y0<0) then
     repeat
           x0:=x0+b;
           y0:=y0+a;
     until (x0>=0) and (y0>=0);
     x:=x0; y:=y0;
end;

procedure wf;
begin
     assign(output,fo);
     rewrite(output);
     write(x,' ',y);
     close(output);
end;

begin
     rf;
     pr;
     wf;
end.

Code mẫu của ladpro98

#include <bits/stdc++.h>

using namespace std;

#define int long long

int bezout(int a, int b) {
    int xa = 1, xb = 0;
    while (b) {
        int q = a / b;
        int r = a - q * b, xr = xa - q * xb;
        a = b; xa = xb;
        b = r; xb = xr;
    }
    return xa;
}

int solve(int a, int b, int c) {
    int g = __gcd(a, b);
    int x = bezout(a, b) * (c / g);
    int p = abs(b / g), q = abs(a / g);
    x = (x % p + p) % p;
    int y = (c - a * x) / b;
    int cur = x + y;
    if (x < 0 || y < 0) cur = -1;
    int yy = (y % q + q) % q;
    int xx = (c - b * yy) / a;
    if (cur == -1 || (min(xx, yy) >= 0 && cur > xx + yy))
        cout << xx << ' ' << yy << endl;
    else
        cout << x << ' ' << y << endl;
}

main() {
    int a1, a2, b1, b2;
    cin >> a1 >> b1 >> a2 >> b2;
    solve(a1, -a2, b2 - b1);
}

Code mẫu của RR

{$R+,Q+}
procedure ee(a,b:int64;var x,y:int64);
var
  x2,y2:int64;
begin
  if (a<b) then ee(b,a,y,x)
  else if (b=0) then
    begin
      x:=1;
      y:=0;
    end
  else
    begin
      ee(b,a mod b,x2,y2);
      x:=y2;
      y:=x2-(a div b)*y2;
    end;
end;
function gcd(a,b:int64):int64;
begin
  if (a=0) or (b=0) then exit(a+b)
  else if a<b then exit(gcd(b,a))
  else exit(gcd(b,a mod b));
end;
var
  d,x1,y1,x2,y2,b,a1,b1,a2,b2,k:int64;
begin
  read(a1,b1,a2,b2);
  d:=gcd(a1,a2);
  b:=(b2-b1) div d;
  ee(a1,a2,y1,y2);
  k:=(y2-y1)*b*d div (a1+a2);
  repeat
    dec(k);
  until (y1-y2)*b+k*(a1+a2) div d<0;
  repeat
    inc(k);
  until (y1-y2)*b+k*(a1+a2) div d>=0;
  writeln(y1*b+k*a2 div d,' ',-y2*b+k*a1 div d);
end.

Code mẫu của hieult

#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
typedef long long ll;
ll a,b,c,d,a1,b1,a2,b2,xo, yo,x,y,t;
void Enter(){
     cin >> a1 >> b1 >> a2 >> b2;
}
ll gcd(ll a, ll b){
     while(b>0){
          ll r=a%b;
          a=b;
          b=r;      
     }
     return a;
}
void ee(ll a, ll b, ll &x, ll &y){
     ll x2, y2;
     if(a<b)ee(b,a,x,y); else if(b==0){
             x=1; y=0;            
     }else {
         ee(b,a%b,x2,y2);  
         x=y2;
         y=(ll)(x2-(a/b)*y2);
     }
}
void swap(ll &x, ll &y){
     ll tg;
     tg= x; x=y; y=tg;
}
ll min(ll x, ll y){
     return (x<y)?x:y;
}
void Solve(){
     if(b1>b2){
           a=a2;    
           b=-a1;
           c=b1-b2;
     }else{
         a=a1; 
         b=-a2;
         c=b2-b1;           
     }
     d=gcd(abs(a),abs(b));
     a/=d; b/=d; c/=d;
     ee(abs(a),abs(b),xo,yo);    
     if(abs(a) < abs(b))swap(xo,yo);
     yo=-yo*c; xo*=c; 
     double tmp1=floor((-xo*1.0)/(b*1.0));  
     double tmp2=floor((yo*1.0)/(a*1.0));
     t=min((ll)(tmp1),(ll)(tmp2));
     x=xo+b*t; y=yo-a*t;
       if(a1*x+b1!=a2*y+b2)swap(x,y);
     cout << x << " " << y << endl;
}

int main(){
    Enter();
    Solve();
    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.