Đồ Án Chương trình giải được ô số sudoku có kích thước 9x9 full five code

17 3K 2
Đồ Án Chương trình giải được ô số sudoku có kích thước 9x9 full five code

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc Mục Lục I.Giới thiệu : 2 1. Lịch sử ra đời: 2 2. Luật chơi: 3 II.Cấu trúc dữ liệu: 5 III.Thuật toán: 5 1. Thuật toán cơ bản: 5 2. Thuật toán cụ thể : 7 IV.Chương trình: 9 V. Kết quả: 16 VI. NHẬN XÉT: 17 Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 1 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc I.Giới thiệu : Sodoku hay còn gọi là Sudoku là một trò chơi trí tuệ nổi tiếng trên thế giới được nhiều người biết đến. Ta hãy cùng tìm hiểu về lịch sử của ô số này nhé ^^. 1. Lịch sử ra đời: Sudoku có lịch sử xa xưa từ hàng ngàn năm. Nó từng đi qua các nền văn hóa cổ, và có lẽ nó bắt nguồn từ Trung Hoa, theo như một tài liệu của Ả rập vào thế kỷ thứ 9. Năm 990, một danh sách những “Ô số kỳ ảo” đã xuất hiện và tỏ ra không khác mấy so với bản Sudoku xuất hiện trong Từ Điển Bách Khoa Ikhwan al-salfa cùa các học giả người Ả Rập. Trong từ điển này, họ gọi nó là wafq. Abraham Ben ibn Ezra - một nhà triết học kiêm chiêm tinh học người Hispanic (Tây Ban Nha - Bồ Đào Nha) gốc Do thái - bắt đầu quảng bá khối vuông buduh ở châu Âu. Ông đi khắp Tây Ban Nha, Ý và các nước khác ở châu Âu để giới thiệu với công chúng về “những ô số kỳ ảo”. Sudoku có thêm một bước tiến hóa mới vào năm 1776 khi một nhà toán học kiêm vật lý học người Thuỵ Sĩ tên Leonhard Euler bắt đầu nghiên cứu và phát triển các luật chơi mà ngày nay ta gọi là luật chơi Sudoku. Năm 1901, một nhà toán học người Pháp tiếp tục công trình này và năm 1959, hai người Mỹ tên là Bose và Shrikhande nối gót theo ông ta. Đi xuyên qua một cuộc hành trình dài lâu và kiên trì, Sudoku lần đầu tiên được xuất bản vào cuối thập niên 1970 trong một tờ tạp chí ở New York. Tờ tạp chí này đã giới thiệu về các ô số kỳ ảo và khuôn nó lại trong một lưới 9x9, tạo thành từ các khối 3x3. Và như thế, Sudoku đã ra đời. Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 2 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc Năm 1986, trong một chuyến đi Mỹ, một nhà xuất bản Nhật Bản, Nikoli, đã khám phá ra các ô số. Họ đặt tên cho nó là SuDoku (Su là số, Doku là đơn độc), và làm cho nó nhanh chóng trở thành một trò chơi phổ biến ở Nhật Bản. Sau hơn 20 năm, một thẩm phán người Hồng Kông gốc New Zealand tên là Wayne Gould tình cờ phát hiện một cuốn sudoku trong một hiệu sách Nhật Bản. Ông đâm nghiền trò chơi số cổ xưa này. Năm 2004, niềm đam mê Sudoku đã đưa Wayne Gould đến với London (Anh). Nhân một chuyến thăm ngẫu nhiên báo The Times, Gould đã thuyết phục tổng biên tập của báo này cho đăng Sudoku bên cạnh các ô chữ. Độc giả lập tức bị cuốn hút và yêu cầu đăng thêm nữa. Chỉ trong vài tuần lễ, các tờ báo trên khắp nước Anh đã thi nhau đăng Sudoku. Từ đó, Sudoku bắt đầu lan rộng sang Mỹ, Canada, Úc, Pháp, Nam Phi và nhiều quốc gia khác. 2. Luật chơi: Luật chơi Sudoku cực kỳ đơn giản, nhưng đáp án đôi khi lại cực kỳ khó giải. Do không cần dùng đến kiến thức số học hay tính toán, Sudoku thích ứng cho mọi người. Vì vậy trẻ em cũng có cơ hội giải được Sudoku thành công như người lớn. Trên thực tế, ở một số nước châu Âu, các em nhỏ đã chiến thắng người lớn trong các cuộc thi đấu Sudoku. Luật chơi như sau: Điền vào những ô trống những con số thích hợp, theo quy luật đơn giản sau: - Các ô ở mỗi hàng (ngang) phải có đủ các số từ 1 đến 9, không cần theo thứ tự. - Các ô ở mỗi cột (dọc) phải có đủ các số từ 1 đến 9, không cần theo thứ tự. - Mỗi miền 3x3, được viền đậm, phải có đủ các số từ 1 đến 9. Trò chơi bắt đầu với một lưới Sudoku, trong đó một số ô đã cho sẵn các con số đúng. Bạn phải suy luận để tìm ra những con số trong các ô trống còn lại. Các đề sudoku mức dễ thường bắt đầu với nhiều con số đã được điền sẵn, do đó bạn sẽ dễ tìm ra đáp án hơn. Càng tìm ra nhiều con số, bạn sẽ càng dễ tìm ra các con số khác. Ngoài khuôn dạng chuẩn có kích thước 9x9 ô, chia làm 3x3 vùng, còn có rất nhiều biến thể khác. Một số biến thể phổ biến như: - Kích thước 4x4 ô chia làm 2x2 vùng - Kích thước 6x6 ô chia làm 2x3 vùng Biến thể với kích thước lớn cũng khá phổ biến: - Kích thước 16x16 ô (Monster SuDoku) - Kích thước 12x12 ô chia làm 4x3 vùng (Dodeka Sudoku) - Kích thước 25x25 ô (Giant Sudoku) - Biến thể có kích thước lớn nhất được phổ biến là 100x100 ô. Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 3 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc VD: Kết quả: Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 4 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc II.Cấu trúc dữ liệu : Trong bài nãy ta chỉ xét đến ô sudoku có kích thước 9x9. Ta có thể biểu diễn ô số sudoku bằng mảng 2 chiều. Và sử dụng kiểu bản ghi cell gồm trường value để chứa giá trị của một ô và trường set là tập hợp các giá trị đề cử cho ô đó. typedef struct cell { int value; int set[10]; }; typedef cell sudoku[10][10]; sudoku a; III.Thuật toán : Có nhiều giải thuật được đưa ra để giải ô số sudoku nhưng ở đây ta sử dụng giải thuật đệ quy quay lui. 1. Thuật toán cơ bản: • Kỹ thuật quay lui (backtracking) như tên gọi của nó, là một quá trình tìm kiếm mà trong quá trình tìm kiếm, nếu ta gặp một hướng lựa chọn không thỏa mãn, ta quay lui về điểm lựa chọn nơi có các hướng khác và thử hướng lựa chọn tiếp theo. Quá trình tìm kiếm thất bại khi không còn điểm lựa chọn nào nữa. Thuật toán quay lui có thể được mô tả bằng đoạn giả mã sau: {Thủ tục này thử cho xi nhận lần lượt các giá trị mà nó có thể nhận} procedure Try(i: Integer); begin for (mọi giá trị có thể gán cho xi) do begin <Thử cho xi := V>; if (xi là phần tử cuối cùng trong cấu hình) then <Thông báo cấu hình tìm được> else begin <Ghi nhận việc cho xi nhận giá trị V (Nếu cần)>; Try(i + 1); {Gọi đệ qui để chọn tiếp xi + 1} Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 5 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc <Nếu cần, bỏ ghi nhận việc thử xi := V, để thử giá trị khác>; end; end; end; Ta có thể trình bày quá trình tìm kiếm lời giải quả thuật toán quay lui bằng cây sau: • Đệ quy (recursion) là một thuật toán được xây dựng dựa trên chính nó. Một chương trình con đệ qui căn bản gồm hai phần. - Phần cơ sở: chứa các tác động của hàm hoặc thủ tục với một số giá trị cụ thể ban đầu của tham số. - Phần đệ qui: định nghĩa tác động cần được thực hiện cho giá trị hiện thời của các tham số bằng các tác động đã được định nghĩa trước đây với kích thước tham số nhỏ hơn. Vd: Tính giai thừa bằng đệ quy int giaithua (int n) { if(n==0||n=1) return(1); else return(n*giaithua(n-1)); } Trong ví dụ trên, quy trình thực hiện như sau: - Khi có lệnh gọi hàm: chẳng hạn giaithua(3) thì máy sẽ ghi nhớ là: giaithua(3) = 3* giaithua(2) và kế tiếp là đi tính giai thừa của 2 thì máy sẽ nhớ là: giaithua(2) = 2* giaithua(1) và theo định nghĩa của hàm thì giaithua(1) = 1 . Sau đó, máy sẽ quay ngược lại tính giai thừa của 2 và kế tiếp là giai thừa của 3 . Cuối cùng, ta được kết quả là : giaithua(3) = 6 • Thuật toán quay lui tổng quát: đệ quy Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 6 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc Thuật toán được mô tả bằng đoạn giả mã sau: quaylui_dequy(k) begin if (s=(s 1 , s 2 , …, s k ) là giải pháp) then xuly(s) else for j from 1 to |A k | do //thử tất cả các giá trị có thể s k = a k j //A k = {a k 1 , a k 2 ,…} if (( s 1 , s 2 , …, s k ) là có triển vọng) then quaylui_dequy(k+1) //xây dựng thành phần tiếp theo endif endfor endif end 2. Thuật toán cụ thể : - Trước khi áp dụng giải thuật đệ quy quay lui để giải ô sudoku,ở mỗi ô, ta lọc trước các giá trị mà ô đó có thể nhận. Thuật toán cụ thể như sau: duyệt lần lượt từng ô xem thử trong cùng hàng, cột, block đã tồn tại giá trị value nào chưa, nếu có thì loại giá trị đó ra khỏi tập các giá trị đề cử. Chẳng hạn, trong ví dụ trên: ở ô [1][1] ta có thể loại ra các giá trị 1, 2, 4, 5, 6, 8, 9. Như vây, sau khi lọc, tập giá trị mà ô đó có thể nhận chỉ gồm {3,7} . Cứ tiếp tục lọc cho đến ô cuối cùng (ô [9][9]) . Mục đích của việc này là nhằm giảm bớt số lần quay lui. Sau đây là các hàm lọc theo hàng, cột, và block. ******************************************** void filter_row(int i, int vl, int num) { int j; for (j=1;j<=n;j++) a[i][j].set[vl]=num; } ******************************************** void filter_col(int j, int vl, int num) { int i; for (i=1;i<=n;i++) a[i][j].set[vl]=num; } ******************************************** void filter_bl(int i, int j, int vl, int num) { Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 7 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc int row=get_bl(i); int col=get_bl(j); for (int t=row;t<=row+2;t++) for (int k=col;k<=col+2;k++) a[t][k].set[vl]=num; } ******************************************** - Sau khi lọc xong, ta dùng thuật toán đệ quy quay lui dựa trên phương pháp thử và sai. Đầu tiên, ta xác định ô đó thuộc hàng i, cột j theo công thức: i=(index-1)/9+1 j=(index-1)%9 Nếu a[i][j] =0 tức là ô đó chưa có lời giải thì bắt đầu duyệt qua các giá trị đề cử và xem thử t có tồn tại trên cùng hàng, cột hay block chưa ,nếu chưa thì điền t vào ô đó. Nếu đã xét đủ 81 ô thì in ra kết quả, còn không đủ thì xét đến ô tiếp theo. Nếu không đặt giá trị đó vào ô đó được thì quay lui. ******************************************** void trycell (int index) { int i,j,t; i=(index-1)/9+1; j=(index-1)%9+1; if (index>tt) tt=index; //dieu kien dung if (!a[i][j].value) { for (t=1;t<=9;t++) if ((!a[i][j].set[t])&&(!valueExisted(t,i,j))) { a[i][j].value=t; //thu sai if (index<81) trycell(index+1); // neu index=81 thi in ket qua else { output(); exit(1); } if (!a[i][j].set[0]) a[i][j].value=0; //quay lui } } else trycell(index +1); } ******************************************** Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 8 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc IV.Chương trình : #include<conio.h> #include<stdio.h> #include<stdlib.h> const int n=9; typedef struct cell { int value; int set[10]; }; typedef cell sudoku[10][10]; sudoku a; int tt=0; void create(); void output(); void filter_row(int i,int vl,int num); void filter_col(int j,int vl,int num); int get_bl(int i); void filter_bl(int i,int j,int vl,int num); int filtercell(int h,int c,int vl,int num); void filter(); int valueExisted(int vl,int h,int c); int errordata(sudoku a); void trycell(int index); void DrawRectang(int left,int top,int width,int height,int color); void write_string(char *str,int x,int y,int color); void introduce(); /*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*/ //doc du lieu tu file input.txt void create() { int i,j,t; FILE *f; f=fopen("input.txt","r"); if (f==NULL) { printf("File khong ton tai ! Kiem tra va dat file intput.txt vao cung thu muc chua file sudoku.exe!"); Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 9 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc getch(); exit(1); } for (i=1;i<=n;i++) for (j=1;j<=n;j++) { fscanf(f,"%d",&t); a[i][j].value=t; } fclose(f); } /*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*/ //xuat ra o so sudoku neu giai duoc void output() { int i,j; printf("\n"); for (i=1;i<=n;i++) { if (i%3==1) printf("\n"); for (j=1;j<=n;j++) { if (j%3==1) printf(" "); printf("%3d",a[i][j].value); } printf("\n"); } getch(); } /*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*/ //ham loc hang void filter_row(int i, int vl, int num) { int j; for (j=1;j<=n;j++) a[i][j].set[vl]=num; } /*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*==*/ //ham loc cot void filter_col(int j, int vl, int num) { int i; Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Page 10 Nhóm 11 [...]... printf("\nO sudoku nay khong co loi giai!"); getch(); } Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Nhóm 11 Page 15 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc V Kết quả: Nguyễn Hoàng Nguyện – Đặng Thị Quỳnh Như Nhóm 11 Page 16 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc VI NHẬN XÉT: Chương trình giải được ô số sudoku có kích thước 9x9 có mức độ từ dễ đến khó Hạn chế của chương trình là nếu... có kích thước 9x9 có mức độ từ dễ đến khó Hạn chế của chương trình là nếu dữ liệu đầu vào quá ít ( mức độ impossible ) thì chương trình có thể không đưa ra được kết quả Bài toán sudoku là bài toán phức tạp nên nhóm chỉ thao tác với chế độ văn bản Đây là đồ án đầu tiên nên khó tránh khỏi sai sót, rất mong sự giúp đỡ của thầy và em xin cảm ơn thầy đã hướng dẫn chúng em SV thực hiện: Nguyễn Hoàng Nguyện... Đặng Thị Quỳnh Như Nhóm 11 Page 12 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc //ham kiem tra du lieu vao int errordata (sudoku a) { int i,j,ok=0; for (i=1;i . 16 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc VI. NHẬN XÉT: Chương trình giải được ô số sudoku có kích thước 9x9 có mức độ từ dễ đến khó. Hạn chế của chương trình là nếu dữ. kích thước lớn cũng khá phổ biến: - Kích thước 16x16 ô (Monster SuDoku) - Kích thước 12x12 ô chia làm 4x3 vùng (Dodeka Sudoku) - Kích thước 25x25 ô (Giant Sudoku) - Biến thể có kích thước. Page 4 Nhóm 11 Đồ án môn học: Cấu trúc dữ liệu GVHD: Lê Quý Lộc II.Cấu trúc dữ liệu : Trong bài nãy ta chỉ xét đến ô sudoku có kích thước 9x9. Ta có thể biểu diễn ô số sudoku bằng mảng

Ngày đăng: 10/04/2015, 16:21

Từ khóa liên quan

Mục lục

  • I.Giới thiệu :

    • 1. Lịch sử ra đời:

    • 2. Luật chơi:

    • II.Cấu trúc dữ liệu:

    • III.Thuật toán:

      • 1. Thuật toán cơ bản:

      • 2. Thuật toán cụ thể :

      • IV.Chương trình:

      • V. Kết quả:

      • VI. NHẬN XÉT:

Tài liệu cùng người dùng

Tài liệu liên quan