bài tập phép nhân...khó quá mọi người giúp đỡ

HTML:
Cho hai số nguyên dương n,m có x, y chữ số ( 1<= x,y < 10000 ) 
yêu cầu tính tích của hai số n,m 
Dữ liệu vào
    dòng 1: ghi hai số x,y là  số lượng chữ số của  n,m, hai số cách nhau một dấu cách
   dòng 2: ghi số nguyên n,
    Dòng 3: ghi số nguyên m 
dữ liệu ra 
    dòng 1: ghi số lượng chữ số của tích n,m
    dòng 2: ghi kết quả của phép nhân
VD TICH.IN           PTICH.OUT
5 3                          7
24586
123                       3024078
ai giúp mình cho xin cai code xử lí bài này với ak...
 

tengiday

Happy life
Bài này kỹ thuật lập trính thôi chứ không khó đâu.
- Đầu tiên về lưu trữ số thì bạn có 2 lựa chọn: dùng mảng của longint hoặc dùng ansistring để lưu. Mình khuyến khích bạn nên lưu số ngược, tức là hàng đơn vị ở index 1 trong mảng.
- Bạn cần 2 functions sau: cộng 2 số và nhân 1 số với 1 chữ số. Bạn thực hiện phép toán bằng tay thế nào thì viết cho chạy như vậy.
- Sau đó function nhân 2 số thì tổng hợp của 2 functions kia lại.

Ví dụ về cộng 2 số dùng chuỗi (assume chuỗi a và b đc lưu ngược nhé):
[ah]
Mã:
function sum(a, b : ansistring; offset : integer) : ansistring;
var i, carry, k, xa, xb, t : integer;
    c : ansistring;
begin
    c := '';
    carry := 0;
    k := max(length(a), length(b) + offset);
    for i := 1 to k do
        begin
            xa := 0;
            if (i <= length(a)) then
                xa := ord(a[i]) - 48;
            xb := 0;
            if (offset < i) and (i <= length(b) + offset) then
                xb := ord(b[i - offset]) - 48;
            t := xa + xb + carry;
            carry := t div 10;
            c := c + chr(t mod 10 + 48);
        end;
    if (carry > 0) then
        c := c + '1';
    exit(c);
end;
[/ah]

Tốc độ: Nếu bạn muốn nhanh thì bạn nên dùng mảng của longint VÀ lưu theo hệ cơ số 10^4, đương nhiên sẽ khó viết hơn một tí.
 
Sửa lần cuối:
hiện tại mình đang chạy trên tp 7.0 nên mình chọn cách lưu trữ bằng mảng.chỗ này mình biết nhưng bạn có thể chỉ rõ hai ham ròi kết hợp tạo thành bài này được ko ak
 

tengiday

Happy life
Để đơn giản thì bạn lưu thế này. Ví dụ số 843 sẽ đc lưu trong mảng a là:
Mã:
[TABLE="width: 500"]
[TR]
[TD]Index i[/TD]
[TD="align: center"][COLOR=#ff0000]1[/COLOR][/TD]
[TD="align: center"][COLOR=#ff0000]2[/COLOR][/TD]
[TD="align: center"][COLOR=#ff0000]3[/COLOR][/TD]
[/TR]
[TR]
[TD]a[i][/TD]
[TD="align: center"]3[/TD]
[TD="align: center"]4[/TD]
[TD="align: center"]8[/TD]
[/TR]
[/TABLE]


Còn cần 1 biến na = 3 để lưu trữ số chữ số của a.
Về phép cộng và nhân thì bạn làm tay thế nào thì viết cho nó chạy y như thế. Mình không có Pascal nên chỉ code nhanh thế này thôi nhé.
[ah]
Mã:
uses math;
type number = array[1..20001] of integer;
var a, b, c : number;
    na, nb, nc : integer;

// in ra số 'a'. Số 'a' có 'na' chữ số.
procedure printNumber(a : number; na : integer);
var i : integer;
begin
    for i := na downto 1 do
        write(a[i]);
    writeln;
end;

// tính tổng của 2 số 'a' và 'b', với 'b' đc dịch sang bên trái 'offset' chữ số.
// kết quả đc lưu vào số 'a'.
procedure sum(var a, b : number; var na : integer; nb, offset : integer);
var i, carry, k, xa, xb, nrs : integer;
begin
    k := max(na, nb + offset);
    carry := 0;
    nrs := 0;
    for i := 1 to k do
        begin
            xa := 0;
            if (i <= na) then
                xa := a[i];
            xb := 0;
            if (offset < i) and (i <= nb + offset) then
                xb := b[i - offset];
            inc(nrs);
            a[nrs] := xa + xb + carry;
            carry := a[nrs] div 10;
            a[nrs] := a[nrs] mod 10;
        end;
    if (carry > 0) then
        begin
            inc(nrs);
            a[nrs] := 1;
        end;
    na := nrs;
end;

// nhân số 'a' với 1 chữ số 'digit'. Kết quá đc lưu ở 'c' với 'nc' chữ số.
procedure multiply_digit(a : number; na, digit : integer; var c : number; var nc : integer);
var i, carry : integer;
begin
    nc := 0;
    carry := 0;
    for i := 1 to na do
        begin
            inc(nc);
            c[nc] := a[i] * digit + carry;
            carry := c[nc] div 10;
            c[nc] := c[nc] mod 10;
        end;
    if (carry > 0) then
        begin
            inc(nc);
            c[nc] := carry;
        end;
end;

// nhân 2 số lớn 'a' và 'b'. Kết quả đc lưu ở 'c' với 'nc' chữ số.
procedure multiply(a, b : number; na, nb : integer; var c : number; var nc : integer);
var i, nd : integer;
    d : number;
begin
    multiply_digit(a, na, b[1], c, nc);
    for i := 2 to nb do
        begin
            multiply_digit(a, na, b[i], d, nd);
            sum(c, d, nc, nd, i - 1);
        end;
end;

BEGIN
    a[1] := 3; a[2] := 4; a[3] := 8; na := 3; // 843
    b[1] := 7; b[2] := 0; b[3] := 9; b[4] := 1; nb := 4; // 1907
    
    multiply(a, b, na, nb, c, nc);
    printNumber(c, nc);
    
END.
[/ah]
Mình nghĩ 2 số 10^4 chữ số thì sẽ mất ít nhất cũng 5 giây. Nếu dùng hệ cơ số 10^4 thì ct sẽ chạy nhanh hơn, nhưng khó viết hơn.
 
Sửa lần cuối:
Top