các bạn giúp với!! xử lí số lớn trong pascal!!

Bài 2. Giai thừa (7 điểm)
Tuấn và Minh mới học phép nhân có nhớ. Các em rất thích thú khi nhận ra rằng chỉ cần kiên trì là các em có thể thực hiện các phép nhân với số chữ số lớn tùy ý. Một ngày chủ nhật, hai em quyết định thi với nhau xem ai làm tính chính xác hơn. Các em đặt ra bài toán sau:
Chọn một số nguyên dương N, tính tích 1.2.3…N (kí hiệu là N!, đọc là N giai thừa) được một số, sau đó tính tổng tất cả các chữ số của số này.
Kết quả tính toán của Tuấn và Minh khác nhau, vì vậy các em quyết định nhờ một anh học sinh giỏi lớp 12 xác định giúp xem ai đúng, ai sai.
Để có thể làm trọng tài cho Tuấn và Minh, em hãy lập chương trình giải quyết bài toán do Tuấn và Minh đặt ra.
Input: Dữ liệu vào cho trong file văn bản có tên GIAITHUA.IN bao gồm nhiều bộ dữ liệu. Mỗi bộ dữ liệu nằm trên 1 dòng chứa một số tự nhiên N duy nhất (1 < N < 2000)
Output: Kết quả đưa ra file văn bản có tên GIAITHUA.OUT. Kết quả của mỗi bộ dữ liệu vào nằm trên một dòng theo thứ tự trong file input và chỉ chứa 1 số nguyên duy nhất là tổng các chữ số của số nguyên N!
GIAITHUA.INGIAITHUA.OUT
2
4
6
2
6
9
 
  • Chủ đề
    giaithua
  • tengiday

    Happy life
    Bạn dùng phép nhân trong hệ cơ số 100 000 đấy. Ví dụ như:
    10! = 3 628 800 = 36 * 100 000 + 28 800.
    Kết quả đc lưu dưới dạng mảng, mỗi giá trị của mảng xem như đơn vị của k * 100 000. Ngoài ra kông cần lưu ý tới số 0 ở cuối số.
    Số đc lưu ngược. trong mảng 'a'. Để hiểu rõ, bạn cho số từ nhỏ tới lớn rồi in ra mảng 'a' ở từng bước 'i'.
    Khuya rồi, code mình test nhanh đây:
    [ah]
    Mã:
    const BASE = 100000;
    var a : array[1..10000] of longint;
        sum, carry, i, j, n, left, right : longint;
        
    BEGIN
        write('N = '); readln(n);
        
        left := 1; right := 1; a[1] := 1;
        for i := 2 to n do
            begin
                carry := 0;
                for j := left to right do
                    begin
                        carry := a[j] * i + carry;
                        a[j] := carry mod BASE;
                        // bỏ số 0 ở cuối
                        if (j = left) and (carry mod BASE = 0) then
                            inc(left);
                        carry := carry div BASE;
                    end;
                if (carry > 0) then
                    begin
                        inc(right);
                        a[right] := carry;
                    end;
            end;
        sum := 0;
        for i := left to right do
            sum := sum + a[i] mod 10 + (a[i] div 10) mod 10 + (a[i] div 100) mod 10 + (a[i] div 1000) mod 10 + (a[i] div 10000) mod 10;
        writeln(sum);
    END.
    [/ah]
     
    Bạn dùng phép nhân trong hệ cơ số 100 000 đấy. Ví dụ như:
    10! = 3 628 800 = 36 * 100 000 + 28 800.
    Kết quả đc lưu dưới dạng mảng, mỗi giá trị của mảng xem như đơn vị của k * 100 000. Ngoài ra kông cần lưu ý tới số 0 ở cuối số.
    Số đc lưu ngược. trong mảng 'a'. Để hiểu rõ, bạn cho số từ nhỏ tới lớn rồi in ra mảng 'a' ở từng bước 'i'.
    Khuya rồi, code mình test nhanh đây:
    [ah]
    Mã:
    const BASE = 100000;
    var a : array[1..10000] of longint;
        sum, carry, i, j, n, left, right : longint;
        
    BEGIN
        write('N = '); readln(n);
        
        left := 1; right := 1; a[1] := 1;
        for i := 2 to n do
            begin
                carry := 0;
                for j := left to right do
                    begin
                        carry := a[j] * i + carry;
                        a[j] := carry mod BASE;
                        // bỏ số 0 ở cuối
                        if (j = left) and (carry mod BASE = 0) then
                            inc(left);
                        carry := carry div BASE;
                    end;
                if (carry > 0) then
                    begin
                        inc(right);
                        a[right] := carry;
                    end;
            end;
        sum := 0;
        for i := left to right do
            sum := sum + a[i] mod 10 + (a[i] div 10) mod 10 + (a[i] div 100) mod 10 + (a[i] div 1000) mod 10 + (a[i] div 10000) mod 10;
        writeln(sum);
    END.
    [/ah]
    cảm ơn cậu nhiều nhé. chúc cậu may mắn và thành đạt nha
     
    Top