กฎ Sudoku
ในเกม Sudoku กริดเก้ากากาคลาสสิกประกอบด้วยเซลล์ 9 × 9 = 81 และยังสร้างกริด 3 × 3 = 9 กริดเก้ากากาขนาดเล็ก จำเป็นต้องกรอกหมายเลข 1 ~ 9 ใน 81 เซลล์ขนาดเล็กและตัวเลขไม่สามารถทำซ้ำได้ในแต่ละแถวคอลัมน์และกริดเก้ากึ่งขนาดเล็กแต่ละอัน
ทักษะ Sudoku
ความคิดของฉัน
การออกแบบโซลูชันและการใช้งาน
มีการใช้อาร์เรย์สองมิติเพียงสองมิติเพื่อจัดเก็บโครงการ Sudoku จะใช้อาร์เรย์หนึ่งมิติเป็นสแต็กและใช้ตัวแปรบูลีนเป็นตัวระบุย้อนกลับ
1. คำจำกัดความของตัวแปร:
ปัญหา VAR = [// นี่คือคำถามของความยากลำบาก 10.7 ที่กล่าวถึงในหนังสือเล่มนี้ [8,0,0,0,0,0,0,0,0], [0,0,3,6,0,0,0,0,0,0,0], [0,7,0,0,9,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,0s0 [0,0,0,0,0,4,5,7,0,0,0,0], [0,0,0,1,0,0,0,0,0,0,0], [0,0,1,0,0,0,0,0,0,8], [0,0,8,0,0,0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0s0,0,0,0,0,0,0,0,0,0s0 stack = [], flag = false;
2. การกำหนดประสิทธิภาพของแผน:
คุณลักษณะการแฮชของวัตถุจาวาสคริปต์ถูกนำมาใช้อย่างเต็มที่ เพื่ออำนวยความสะดวกในการดีบักค่าส่งคืนของฟังก์ชั่นคือ 0 เมื่อถูกต้องและมีสามสถานการณ์เมื่อไม่ถูกต้อง: ความขัดแย้งแถวความขัดแย้งคอลัมน์และความขัดแย้งกริดเก้าส่วนซึ่งกลับมา 1, 2 และ 3 ตามลำดับ ฉันใช้มันในการตัดสินก่อนหน้านี้และต่อมาได้เพิ่มการตัดสินยี่สิบเฟรมที่เกี่ยวข้อง ฟังก์ชั่นนี้ไม่ได้ใช้อีกต่อไปเมื่อค้นหาคำตอบ
ฟังก์ชั่น checkValid (sudo) {ให้ subsudo = {} // ตัวแปรเสริมที่ใช้เพื่อตรวจสอบว่ากริดที่เก้าขัดแย้งกับ (ให้ i = 0; i <9; i ++) {ให้แถว = {}, col = {} // ตัวแปรเสริมหรือไม่ sudo [i] [j], cur2 = sudo [j] [i] // ตัวแปรที่ได้รับอนุญาตเสร็จสิ้นการตัดสินแถวและคอลัมน์ในเวลาเดียวกันถ้า (แถว [cur1]) // องค์ประกอบปัจจุบันปรากฏขึ้นในแถวและการตัดสินของศูนย์ได้รับการปรับให้เหมาะสม เมื่อคีย์คือ 0 ค่าคือ 0 ไม่จำเป็นต้องมีการตัดสินเพิ่มเติม กลับ 1; // ส่งคืนรหัสข้อผิดพลาดอื่น ๆ แถว [cur1] = cur1 // องค์ประกอบปัจจุบันไม่ปรากฏในแถวและเก็บไว้ในตัวแปรเสริมถ้า (col [cur2]) // การตัดสินของคอลัมน์คล้ายกับแถว การตัดสินของศูนย์ได้รับการปรับให้เหมาะสม เมื่อคีย์คือ 0 ค่าคือ 0 และไม่จำเป็นต้องมีการตัดสินเพิ่มเติม กลับ 2; else col [cur2] = cur2; ให้ key = math.floor (i/3)+'-'+math.floor (j/3) // คีย์ที่แตกต่างกันถูกสร้างขึ้นสำหรับกริดเก้าลูกค้าที่แตกต่างกันถ้า (subsudo [key]) {// คำพิพากษาของศูนย์อยู่แล้วและการตัดสินของศูนย์ได้รับการปรับให้เหมาะสม เมื่อคีย์คือ 0 ค่าคือ 0 และไม่จำเป็นต้องมีการตัดสินเพิ่มเติมถ้า (subsudo [key] [cur1]) // การตัดสินของกริดเก้าลูกค้าจะคล้ายกับแถวของแถวกลับ 3 subsudo [key] [cur1] = cur1}} และบันทึกองค์ประกอบแรกลงไปใน subsudo [key] [cur1] = cur1}}} return 0; // โปรแกรมสามารถเรียกใช้สิ่งนี้โดยระบุว่าแผนนั้นถูกต้อง} 3. การกำหนดหมวดหมู่ที่เกี่ยวข้องยี่สิบ หลักการนั้นเหมือนกับการตัดสินโดยรวมและไฮไลท์อยู่ในตำแหน่งของตารางเก้ากรงขนาดเล็ก ฟังก์ชั่น check20grid (sudo, i, j) {let row = {}, col = {}, subsudo = {} // ตัวแปรจัดหาสำหรับ (ให้ k = 0; k <9; k ++) {ให้ cur1 = sudo [i] [k], cur2 = sudo [k] เมื่อคีย์คือ 0 ค่าคือ 0 และไม่จำเป็นต้องมีการตัดสินเพิ่มเติมหาก (แถว [cur1]) กลับ 1; // ส่งคืนรหัสข้อผิดพลาดอื่น ๆ แถว [cur1] = cur1 // องค์ประกอบปัจจุบันไม่ปรากฏในแถวและเก็บไว้ในตัวแปรเสริม} ถ้า (cur2) {// คำพิพากษาของคอลัมน์คล้ายกับแถว การตัดสินของการสูญเสียศูนย์ได้รับการปรับให้เหมาะสม ค่าคือ 0 เมื่อคีย์คือ 0 ไม่จำเป็นต้องมีการตัดสินเพิ่มเติมหาก (col [cur2]) กลับ 2; else col [cur2] = cur2; } // พิกัดของตัวแปรลูปแปลงไปยังกริดที่เก้าให้คีย์ = sudo [math.floor (i/3)*3 + math.floor (k/3)] [math.floor (j/3)*3 + math.floor (k%3)] ถ้า (subsudo] การตัดสินของการสูญเสียศูนย์ได้รับการปรับให้เหมาะสม ค่าคือ 0 เมื่อคีย์คือ 0 ไม่จำเป็นต้องมีการตัดสินเพิ่มเติม 3 else subsudo [key] = key} return 0;}4. การแก้ปัญหาการสำรวจ
การใช้องค์ประกอบที่มีค่าเริ่มต้นเป็นศูนย์ในสถานะองค์ประกอบเป็นคุณสมบัติที่รอดำเนินการและด้วยความช่วยเหลือของสแต็กจะไม่มีการเปิดพื้นที่เก็บข้อมูลเพิ่มเติม
ฟังก์ชั่น findanswer () {สำหรับ (ให้ i = 0; i <9; i ++) {สำหรับ (ให้ j = 0; j <9;) {ถ้า (ปัญหา [i] [j] === 0 || แฟล็ก) {// ตำแหน่งปัจจุบันคือการประมวลผลครั้งแรกขององค์ประกอบที่จะถูกกำหนดหรือกลับไปยังตำแหน่งปัจจุบัน สถานการณ์ทั้งสองดูเหมือนจะแตกต่างกัน แต่ในความเป็นจริงการประมวลผลเหมือนกัน เพิ่ม 1 ด้วยตัวเองธง = เท็จ; ให้ k = ปัญหา [i] [j] + 1; // ค้นหาเพื่อย้ายไปสู่มูลค่าทางกฎหมายถัดไปในขณะที่ (k <10) {// วนลูปเพื่อค้นหาปัญหามูลค่าทางกฎหมายถัดไป [i] [j] = k; // กรอกข้อมูล IF (Check20Grid (ปัญหา, i, j) == 0) {// ค่าเริ่มต้นถูกกฎหมายและการตัดสินยี่สิบเฟรมที่เกี่ยวข้องคือ stack.push ([i, j ++]) // การจัดเก็บจุด traceback และก้าวเข้าสู่การหยุดพัก; } k ++; } if (k> 9) {// ค่าทางกฎหมายไม่สามารถพบได้ที่ตำแหน่งปัจจุบันปัญหา traceback [i] [j] = 0; // กลับมาก่อนการติดตามกลับให้ rt = stack.pop (); // ดึงข้อมูล traceback ในสแต็กถ้า (! rt) // ไม่มีการตัดสินทางออก, return 0 กลับ 0; i = rt [0] // travel j = rt [1] flag = true; }} else {// หมายเลขตำแหน่งปัจจุบันได้รับ j ++; }}} return 1; // ประสบความสำเร็จในการพบชุดของโซลูชัน}