Hotline: 024.62511017

024.62511081

  Trang chủ   Sản phẩm   Phần mềm Dành cho nhà trường   Phần mềm Hỗ trợ học tập   Kho phần mềm   Liên hệ   Đăng nhập | Đăng ký

Tìm kiếm

School@net
 
Xem bài viết theo các chủ đề hiện có
  • Hoạt động của công ty (726 bài viết)
  • Hỗ trợ khách hàng (498 bài viết)
  • Thông tin tuyển dụng (57 bài viết)
  • Thông tin khuyến mại (80 bài viết)
  • Sản phẩm mới (216 bài viết)
  • Dành cho Giáo viên (549 bài viết)
  • Lập trình Scratch (3 bài viết)
  • Mô hình & Giải pháp (156 bài viết)
  • IQB và mô hình Ngân hàng đề kiểm tra (127 bài viết)
  • TKB và bài toán xếp Thời khóa biểu (242 bài viết)
  • Học tiếng Việt (183 bài viết)
  • Download - Archive- Update (289 bài viết)
  • Các Website hữu ích (70 bài viết)
  • Cùng học (92 bài viết)
  • Learning Math: Tin học hỗ trợ học Toán trong nhà trường (78 bài viết)
  • School@net 15 năm (154 bài viết)
  • Mỗi ngày một phần mềm (7 bài viết)
  • Dành cho cha mẹ học sinh (124 bài viết)
  • Khám phá phần mềm (122 bài viết)
  • GeoMath: Giải pháp hỗ trợ học dạy môn Toán trong trường phổ thông (36 bài viết)
  • Phần mềm cho em (13 bài viết)
  • ĐỐ VUI - THƯ GIÃN (363 bài viết)
  • Các vấn đề giáo dục (1210 bài viết)
  • Bài học trực tuyến (1037 bài viết)
  • Hoàng Sa - Trường Sa (17 bài viết)
  • Vui học đường (275 bài viết)
  • Tin học và Toán học (220 bài viết)
  • Truyện cổ tích - Truyện thiếu nhi (180 bài viết)
  • Việt Nam - 4000 năm lịch sử (97 bài viết)
  • Xem toàn bộ bài viết (8223 bài viết)
  •  
    Đăng nhập/Đăng ký
    Bí danh
    Mật khẩu
    Mã kiểm traMã kiểm tra
    Lặp lại mã kiểm tra
    Ghi nhớ
     
    Quên mật khẩu | Đăng ký mới
     
    Thành viên có mặt
    Khách: 7
    Thành viên: 0
    Tổng cộng: 7
     
    Số người truy cập
    Hiện đã có 89678417 lượt người đến thăm trang Web của chúng tôi.

    Thêm – Bớt: Một thuật giải độc đáo

    Ngày gửi bài: 27/01/2009
    Số lượt đọc: 3497

    Xuân này xin giới thiệu với bạn đọc một thuật giải được ứng dụng trong các kỹ thuật giấu dữ liệu (tin mật) trong các môi trường đa phương tiện như ảnh, video, audio…Thuật giải luôn luôn cho phương án tối ưu và điều kỳ lạ thể hiện ở tính đơn giản trong thao tác cũng như trong lập luận về tính đúng của thuật giải.

    Bài toán

    Trên bàn đặt một bộ bài gồm n-1 quân bài ghi lần lượt các số hiệu 1, 2 ,…, n-1, 3 £ n £10000. Trọng tài chỉ định bạn lấy k quân bài. Sau đó trọng tài đưa ra một số nguyên dương s. Bạn cần cố gắng thực hiện ít nhất m thao tác thuộc một trong hai loại + hoặc - sau đây:

    +v lấy thêm quân bài số hiệu v từ trên bàn,

    -vbỏ bớt quân bài số hiệu v trên tay,

    để cuối cùngđạt được hệ thức

    t mod n = s mod n(*)

    trong đó t là tổng số hiệu các quân bài có trên tay bạn sau khi bạn đã hoàn tất m thao tác.

    n = 8; s = 22;Trên tay giữ k = 3 quân bài 2, 3, 6.

    Lời giải: Bỏ quân bài 2, lấy thêm quân bài 5.

    t = 3+6+5 = 14,

    t mod 8 = 14 mod 8 = 6 = s mod 8 = 22 mod 8.

    Thí dụ, với n = 8, trọng tài cho số s = 22 và chỉ định bạn lấy k = 3 quân bài là 2, 3 và 6.

    Nếu bạn bỏ quân bài 2 và lấy quân bài 5 thì tổng t = 3 + 6 + 5 = 14. Khi đó

    t mod n = 14 mod 8 = 6 = s mod n = 22 mod 8.

    Vậy một lời giải cho bộ dữ liệu này là

    Thực hiện 2 thao tác: -2 và +5

    Thuật toán

    Ta sẽ chứng minh rằng với không quá 2 thao tác (+) lấy thêm / (-) bỏ bớt một quân bài ta có thể đạt được hệ thức (*).

    Trước hết ta nhắc lại các phép toán đồng dư. Với số nguyên dương n cho trước ta xét tập các số dư trong phép chia một số tự nhiên cho n, mod n, Zn = {0,1,2,…,n-1}. Trên Zncác phép toán cộng và nhân được thực hiện như bình thường sau đó lấy kết quả chia dư cho n. Phép toán lấy số đối của số x cho ta n-x. Phép trừ x-y được đổi thành phép cộng x với số đối của y. Ta có

    • Cộng: (x + y) mod n
    • Nhân: x*y mod n
    • Lấy số đối của x: n - x
    • Trừ: (x + (n-y)) mod n.

    Hãy tưởng tượng các số của Zn là 0, 1, …, n-1 được bố trí trên một vòng tròn như trên mặt đồng hồ. Để tính tổng x+y ta xuất phát từ x và di chuyển y bước theo chiều kim đồng hồ (còn gọi là di chuyển xuôi), mỗi bước ta chuyển qua một số. Kết quả sẽ là điểm dừng cuối cùng. Để tính hiệu x - y ta cũng xuất phát từ x và di chuyển y bước theo chiều ngược lại (di chuyển ngược). Để ý rằng, trên vòng tròn,di chuyển xuôi y bước sẽ cho cùng kết quả như di chuyển ngược (n-y) bước, và ngược lại, di chuyển ngược y bước sẽ tương đương như di chuyển xuôi (n-y) bước. Điều này có nghĩa là muốn thêm b đơn vị cho đại lượng t ta có thể bớt (n-b) đơn vị và ngược lại, muốn bớt b đơn vị từ đại lượng t ta có thể thêm cho t (n-b) đơn vị. Ta cũng để ý rằng số hiệu của mọi quân bài đều nhỏ thua n và mỗi quân bài hoặc là có trên tay người chơi, hoặc là nằm trên bàn. Vì lẽ trên, đôi khi người ta nói tính toán theo đồng dư (modulo) chính là tính toán trên vòng tròn.

    Bạn cũng cần ghi nhớ tính chất sau đây:

    Với mọi số tự nhiên x, y và n, n > 0 và với mọi phép toán số học qÎ {+, -,*} ta luôn có

    (x q y) mod n = ((x mod n) q (y mod n)) mod n

    Vì lũy thừa nguyên dương tương đương với phép nhân liên tiếp, ta suy ra hệ quả sau:

    ak mod n = (a mod n)k mod n

    Công thức trên cho ta quy tắc dễ hiểu sau đây: Khi tính trị của các biểu thức số học chỉ chứa các phép toán cộng, trừ và nhân trong trong Znta có thể thực hiện phép lấy số dư mod n trên các hạng tử và các kết quả trung gian.

    Sau khi đã biết các giá trị input là n, k, s và số hiệu các quân bài cần lấy trên tay, tagán trị cho mảng a[1..n-1] như sau: a[i] = 1 cho biết quân bài i có trên tay, ngược lại, a[i] = 0 cho biết quân bài i còn nằm trên bàn. Với thí dụ đã cho, trọng tài yêu cầu ta 3 quân bài có số hiệu 2, 3 và 6 nên a = (0,1,1,0,0,1,0) ứng với a[2] = a[3] = a[6] = 1, các giá trị a[i] còn lại đều bằng 0.

    Ta tính tổng số hiệu của các quân bài có trong tay lúc đầu và đặt trong biến t. Sau đó ta tính t := t mod n và s := s mod n. Với thí dụ đã cho ta tính được

    t = 2+3+6 = 11, do đó t mod n = t mod 8 = 3

    và s mod 8 = 22 mod 8 = 6

    Tức là t = 3 và s = 6.

    Giả sử t ³ s, ta đặt b = t - s và xét các trường hợp loại trừ nhau sau đây:

    1.b = 0:Hệ thức (*) đã thỏa, ta không phải làm gì. Ta thông báo m = 0, trong đó m là số thao tác +/- cần thực hiện.

    2.Quân bài b có trên tay, tức là a[b] = 1: Ta chỉ việc bỏ quân bài này xuống, khi đó tổng t sẽ giảm b đơn vị theo mod n.

    3.Quân bài (n-b) có trên bàn, tức là a[n-b] = 0: Ta chỉ việc lấy thêm quân bài này. Khi đó tổng t sẽ được thêm (n-b) đơn vị theo mod n, điều này tương đương với việc giảm tổng t đi b đơn vị theo mod n.

    4. Nếu không xảy ra các trường hợp 1, 2 và 3 như trên, tức là b ¹ 0, a[b] = 0, a[n-b]=1, ta tiến hành như sau:

    Tìm hai quân bài u và v thỏa các điều kiện sau

    ·Quân bài u có trên tay, a[u] = 1,

    ·Quân bài v có trên bàn, a[v] = 0,

    ·u = (k*b) mod n ; v = ((k-1)*b) mod n, k là một số tự nhiên. Điều này có nghĩa là u lớn hơn v b đơn vị theo mod n.

    Nếu tìm được hai quân bài u và v như trên ta sẽ thực hiện hai thao tác: bỏ quân bài u (-u) và lấy thêm quân bài v (+v). Khi đó tổng t sẽ được tăng giảm một lượngb theo mod n. Thật vậy,

    (u - v) mod n = (((k*b) mod n) - (((k-1)*b) mod n)) mod n =

    (k*b - (k-1)*b) mod n = b.

    Trường hợp t < s ta phải thêm b = s -t đơn vị cho cho t. Việc này tương đương với giảmt bớt (n-b) đơn vị. Đặt b = n-b rồi lặp lại thủ tục trên sẽ cho ta kết quả tương ứng.

    Ta chứng minh rằng nếu gặp tình huống 4 thì bao giờ cũng có thể tìm được hai quân bài u và v như đã mô tả. Trên hai ngàn năm trước nhà toán học Cổ Hylạp Diophantus đã chứng minh định lý sau:

    Định lý Cho phương trình ax mod n = b mod n, với các hệ số a, b, n là các số tự nhiên, n> 0. Gọi d là ước chung lớn nhất của a và n, d = (a,n). Khi đó

    a) Nếu d không là ước của b thì phương trình vô nghiệm.

    b) Nếu b = kd thì phương trình có đúng d nghiệm trong tập Zn. Các nghiệm này có dạng (x + i(n/d) ) mod n, trong đó x là một nghiệm tùy ý, i = 0,1,2...(d-1).

    Phương trình ax mod n = b mod n được người đời sau gọi là phương trình Diophantus.

    Chứng minh

    Nếu x là nghiệm của phương trình ax mod n = b mod n thì ax vàb có cùng số dư theo mod n nên hiệu của chúng sẽ chia hết cho n, ax – b = kn, hay ax – kn = b. Mặt khác, do d = (a,n) nên a và n đều chia hết cho d và do đó ax-kn cũng chia hết cho d, thế tức là b phải chia hết cho d. Giả sử b = md tức là phương trình có nghiệm. Gọi x là nghiệm nguyên dương nhỏ nhất của phương trình trên ta dễ dàng kiểm tra được rằng x+i(n/d), i = 0,1,…,(d-1) cũng là nghiệm của phương trình đó. Thật vậy, ta để ý rằng nếu d là ước chung lớn nhất của a và n thì an/d chính là bội chung nhỏ nhất của chúng, nghĩa là an/d chia hết cho a và n. Ta có

    a(x+i(n/d)) mod n = ((ax mod n) + (i(an)/d) mod n) mod n = (b mod n + 0)mod n= b mod n. Ta chứng minh xong.

    Thí dụ 1. Giải phương trình sau

    6x mod 9 =21 mod 9

    Phương trình trên tương đương với phương trình sau:

    6x mod 9 = 3

    Ta có d = (6,9) = 3. Vì 3 là ước của vế phải nên phương trình đã cho có 3 nghiệm. Dễ thấy x = 2 là một nghiệm của phương trình. Vậy các nghiệm của phương trình dưới dạng tổng quat là

    x + i(n/d) = 2 + i(9/3) = 2 + 3i, i = 0, 1, 2

    Cụ thể là x1 = 2, x2 = 5 và x3 = 8 là 3 nghiệm trong tập Z9 = {0, 1, 2, 3, 4, 5, 6, 7, 8}.

    Thí dụ 2. Giải phương trình

    4x mod 12 = 5

    Ta có, d = (4,12) = 4 không phải là ước của 5. Phương trình vô nghiệm.

    Trở lại bài toán trên, khi gặp tình huống 4 ta có a[b] = 0 và a[n-b] = 1. Xét phương trìnhbx mod n = (n-b) mod n. Vì 1 £ b < n nên 1 £ n-b < n và do đó(n-b) mod n = n-b, phương trình đã cho có thể viết lại là bx mod n = n-b.

    Theo tính chất: ước chung lớn nhất của hai số tự nhiên (a,b) sẽ không đổi nếu ta thay số lớn nhất trong hai số đó bằng hiệu của nó với số thứ hai, đặt d = (b,n), ta có d =(b,n-b), tức là n-b chia hết cho d, do đó phương trình bx mod n = n-b luôn có nghiệm. Từ nhận xét này suy rarằng vòng lặp repeat trong đoạn trình dưới đây luôn kết thúc.

    u := b;

    repeat

    v := u;

    u := (u+b) mod n;

    until a[u] = 1;

    Do phương trìnhbx mod n = n-b có nghiệm nên sẽ tồn tại một giá trị k để u = kb mod n = n-b. Do a[n-b] = 1 nên vòng lặp sẽ kết thúc với giá trị u=kb mod n. Vì v mang giá trị sát trước của u nên v = (k-1)b mod n.

    Ta có thuật toán sau đây

    1. Đọc dữ liệu vào các biến n, k và s

    2. Khởi trị cho mảng a[1..n-1] với a[i] = 1 nếu quân bài i có trên tay, a[i] = 0 nếu quân bài i còn trên bàn.

    3. Tính t = tổng số hiệu các quân bài có trên tay.

    4. Tính t := t mod n; s := s mod n.

    5. Nếu t ³ s: đặt b := t - s; ngược lại đặt b := n - (s - t).

    Ý nghĩa: cần giảm b đơn vị từ tổng t để đạt hệ thức

    t mod n = s mod n (*)

    6. Xét các trường hợp loại trừ nhau sau đây

    6.1 b = 0: Đặt m = 0; Stop.

    6.2 a[b] = 1 (Quân bài b có trên tay):

    Thực hiện m = 1 thao tác

    -b:Bỏ quân bài b;

    Stop.

    6.3 a[b] = 0 và a[n-b] = 0 (Quân bài b không có trên tay, quân bài (n-b) có trên

    bàn):

    Thực hiện m = 1 thao tác

    +(n-b):Lấy quân bài (n-b);

    Stop.

    6.4 a[b] = 0 và a[n-b] = 1: (Quân bài b không có trên tay, quân bài (n-b) không có

    trên bàn)

    6.4.1 Tính u và v

    u := b;

    repeat

    v := u;

    u := (u+b) mod n;

    until a[u] = 1;

    6.4.2 Thông báo: Thực hiện m = 2 thao tác

    -u: Bỏ quân bài u

    +v: Lấy quân bài v.

    6.4.3 Stop

    Từ chứng minh trên ta rút ra độ phức tạp của thuật toán là O(n) vì trong trường hợp xấu nhất ta duyệt 1 lần mảng a.

    NXH

    School@net



     Bản để in  Lưu dạng file  Gửi tin qua email


    Những bài viết khác:



    Lên đầu trang

     
    CÔNG TY CÔNG NGHỆ TIN HỌC NHÀ TRƯỜNG
     
    Phòng 804 - Nhà 17T1 - Khu Trung Hoà Nhân Chính - Quận Cầu Giấy - Hà Nội
    Phone: 024.62511017 - 024.62511081
    Email: kinhdoanh@schoolnet.vn


    Bản quyền thông tin trên trang điện tử này thuộc về công ty School@net
    Ghi rõ nguồn www.vnschool.net khi bạn phát hành lại thông tin từ website này
    Site xây dựng trên cơ sở hệ thống NukeViet - phát triển từ PHP-Nuke, lưu hành theo giấy phép của GNU/GPL.