kết quả từ 1 tới 3 trên 3

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

  1. #1
    Ðến Từ
    Nam Định
    Thành Viên Thứ: 368445
    Giới tính: Nam
    Bài gửi
    19

    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.IN GIAITHUA.OUT
    2
    4
    6
    2
    6
    9
    Quick reply to this message Trả lời       


  2. #2
    Ðến Từ
    TP. Hồ Chí Minh
    Thành Viên Thứ: 56897
    Giới tính: Nam
    Bài gửi
    881

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

    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:
    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.
    LCD: 13.3" 1920x1080 IPS
    CPU: Intel i7 - 4700MQ (2.4 GHz - 3.4 GHz)
    GPU: Nvidia GTX 765m with GDDR5 2GB
    RAM: 2x8GB G.Skill 2133
    HDD: Samsung SSD 850 Pro 512 GB
    2 kg.

  3. Đã cảm ơn tengiday:


  4. #3
    Ðến Từ
    Nam Định
    Thành Viên Thứ: 368445
    Giới tính: Nam
    Bài gửi
    19

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

    Trích Nguyên văn bởi tengiday Xem bài viết
    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:
    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.
    cảm ơn cậu nhiều nhé. chúc cậu may mắn và thành đạt nha

  5. Đã cảm ơn hoangtungok123:


Nhãn