Aturan Sudoku
Dalam game Sudoku, grid sembilan kandang klasik yang terdiri dari 9 × 9 = 81 sel, dan juga membentuk 3 × 3 = 9 grid sembilan kandang kecil. Diperlukan untuk mengisi angka 1 ~ 9 dalam 81 sel kecil, dan angka tidak dapat diulang di setiap baris, kolom dan setiap kisi sembilan kandang kecil.
Keterampilan Sudoku
Pikiranku
Desain dan Implementasi Solusi
Hanya array dua dimensi yang digunakan untuk menyimpan skema Sudoku, array satu dimensi digunakan sebagai tumpukan, dan variabel boolean digunakan sebagai identifikasi backtrack.
1. Definisi Variabel:
VAR Masalah = [// Ini adalah pertanyaan tentang kesulitan 10.7 yang disebutkan dalam buku ini [8,0,0,0,0,0,0,0], [0,7,0,0,0,0,0,0], [0,5,0,0,0,7,0,0,0,0,0], [0,5,0,0,0,7,7,0,0,0,0], [0,5,0,0,0,7 [0,0,0,0,0,4,5,7,0,0,0], [0,0,0,1,0,0,0,0,3,0], [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,9,0,0,0,0,0,0 stack = [], flag = false;
2. Penentuan efektivitas rencana:
Fitur hashing dari objek JavaScript sepenuhnya digunakan. Untuk memfasilitasi debugging, nilai pengembalian fungsi adalah 0 ketika valid, dan ada tiga situasi ketika tidak valid: konflik baris, konflik kolom, dan konflik sembilan bagian grid, yang masing-masing kembali 1, 2, dan 3. Saya menggunakannya dalam penilaian awal, dan kemudian menambahkan penilaian dua puluh bingkai yang relevan. Fungsi ini tidak lagi digunakan saat mencari jawabannya.
function checkValid (sudo) {let subsudo = {} // variabel tambahan yang digunakan untuk menentukan apakah grid kesembilan konflik untuk (biarkan i = 0; i <9; i ++) {let row = {}, col = {} // variabel auxiliary yang digunakan untuk menentukan apakah baris dan konflik kolom untuk konflik untuk jum (let j = 0; sudo [i] [j], cur2 = sudo [j] [i] // variabel resmi menyelesaikan penilaian baris dan kolom pada saat yang sama jika (baris [cur1]) // elemen saat ini telah muncul di baris, dan penilaian nol dioptimalkan. Ketika kuncinya adalah 0, nilainya adalah 0, tidak ada penilaian tambahan yang diperlukan. Kembali 1; // Kembalikan kode kesalahan lain baris [cur1] = cur1 // elemen saat ini tidak muncul di baris dan disimpan dalam variabel tambahan jika (col [cur2]) // penilaian kolom mirip dengan baris. Penghakiman nol dioptimalkan. Ketika kuncinya adalah 0, nilainya adalah 0, dan tidak perlu penilaian tambahan. Kembali 2; lain col [cur2] = cur2; Biarkan Key = Math.floor (I/3)+'-'+Math.floor (j/3) // Kunci yang berbeda dihasilkan untuk berbagai kisi klien yang berbeda jika (subsudo [kunci]) {// Penilaian nol sudah ada, dan penilaian nol dioptimalkan. Ketika kuncinya adalah 0, nilainya adalah 0, dan tidak perlu untuk penilaian tambahan jika (subsudo [kunci] [cur1]) // penilaian grid sembilan-klien mirip dengan baris mengembalikan 3 hal lain subsudo [kunci] [cur1ion] = cur1} else {// Ini adalah elemen pertama dalam grid nenek nenek ninum kecil subsudo slubudo {// ini adalah elemen pertama dalam grid kecil nine-dish subsudo {ini adalah {ini adalah elemen pertama dalam grid kecil nine-dish Subsudo Subsudo [ Nine-Dish Grid dan simpan elemen pertama ke dalamnya subsudo [key] [cur1] = cur1}}} return 0; // program dapat menjalankan ini, menunjukkan bahwa rencana tersebut valid} 3. Penentuan dua puluh kategori yang relevan Prinsipnya sama dengan penilaian keseluruhan, dan puncaknya terletak pada posisi kisi-kisi sembilan kandang kecil. Fungsi check20grid (sudo, i, j) {let row = {}, col = {}, subsudo = {} // variabel pasokan untuk (biarkan k = 0; k <9; k ++) {let cur1 = sudo [i] [k], cur2 = sudo [k] [j] if (cur1) = sudo. Ketika kunci adalah 0, nilainya adalah 0, dan tidak perlu untuk penilaian tambahan jika (baris [cur1]) kembali 1; // Kembalikan kode kesalahan lain baris [cur1] = cur1 // elemen saat ini tidak muncul di baris, dan disimpan dalam variabel tambahan} if (cur2) {// penilaian kolom mirip dengan baris. Penghakiman atas kehilangan nol dioptimalkan. Nilainya adalah 0 ketika kunci adalah 0. Tidak perlu untuk penilaian tambahan jika (col [cur2]) kembali 2; lain col [cur2] = cur2; } // Koordinat variabel loop konversi ke grid kesembilan Let Key = sudo [math.floor (i/3)*3 + math.floor (k/3)] [math.floor (j/3)*3 + math.floor (k%3)] if (subsudo [kunci]) // penilaian ninth. Penghakiman atas kehilangan nol dioptimalkan. Nilainya adalah 0 ketika kunci adalah 0.4. Solusi Traversal
Menggunakan elemen dengan nilai awal nol dalam keadaan elemen adalah fitur yang tertunda, dan dengan bantuan tumpukan, tidak ada ruang penyimpanan tambahan yang dibuka.
fungsi findanswer () {for (biarkan i = 0; i <9; i ++) {for (biarkan j = 0; j <9;) {if (masalah [i] [j] === 0 || flag) {// Posisi saat ini adalah pemrosesan pertama dari elemen yang akan ditentukan atau kembali ke posisi saat ini. Dua situasi tampaknya berbeda, tetapi sebenarnya pemrosesannya sama. Tambahkan 1 sendiri bendera = false; Biarkan k = masalah [i] [j] + 1; // Cari untuk bergerak menuju nilai hukum berikutnya sementara (k <10) {// loop untuk menemukan masalah nilai hukum berikutnya [i] [j] = k; // Isi if (check20grid (masalah, i, j) == 0) {// default legal, dan penilaian dua puluh bingkai yang relevan adalah stack.push ([i, j ++]) // penyimpanan titik traceback dan melangkah ke istirahat; } k ++; } if (k> 9) {// Nilai hukum tidak dapat ditemukan pada posisi saat ini, masalah traceback [i] [j] = 0; // kembali sebelum traceback let rt = stack.pop (); // Ambil informasi traceback di stack if (! Rt) // tidak ada penilaian solusi, kembalikan 0 kembali 0; i = rt [0] // travel j = rt [1] flag = true; }} else {// Nomor posisi saat ini diberikan j ++; }}} return 1; // berhasil menemukan serangkaian solusi}