Inkara นักคณิตศาสตร์ชาวฟินแลนด์ใช้เวลาสามเดือนในการออกแบบปริศนา Sudoku ที่ยากที่สุดในโลก และมีเพียงคำตอบเดียวเท่านั้น Inkara กล่าวว่าเฉพาะนักคิดที่เร็วที่สุดและจิตใจที่ฉลาดที่สุดเท่านั้นที่จะสามารถทำลายเกมได้
วันนี้ มีข่าวจาก Tencent บอกว่าชายชราชาวจีนทำลายตารางเก้าตารางที่ยากที่สุดในโลกได้ภายในสามวัน แม้ว่าชายชราจะเปลี่ยนตัวเลขในท้ายที่สุด แต่มันก็กระตุ้นความสนใจของฉันและต้องการแก้ปัญหาผ่าน โปรแกรมคอมพิวเตอร์ผมจึงพักอยู่ที่หอพักช่วงบ่ายและในที่สุดก็แก้ไขได้สำเร็จ ซอร์สโค้ดของโปรแกรมมีดังนี้
คัดลอกรหัสรหัสดังต่อไปนี้:
หมายเลขแพ็คเกจเกม;
จุดเรียนสาธารณะ {
int col;//หมายเลขบรรทัด
แถว int ส่วนตัว;//หมายเลขคอลัมน์
การตั้งค่าสถานะบูลีนส่วนตัว // ไม่ได้ตั้งค่า True
มูลค่า int ส่วนตัว
//จุดก่อสร้าง
จุดสาธารณะ (int col, แถว int, ธงบูลีน, ค่า int) {
ซุปเปอร์();
this.col = คอ;
this.row = แถว;
this.flag = ธง;
this.value = ค่า;
-
โมฆะสาธารณะ changeFlag() {
ธง = !ธง;
-
getFlag บูลีนสาธารณะ () {
ธงส่งคืน;
-
สาธารณะ int getValue() {
ค่าส่งคืน;
-
setValue โมฆะสาธารณะ (มูลค่า int) {
this.value = ค่า;
-
บูลีนสาธารณะ canHere (จุด [] [] pArr) {
บูลีน cb = canCol(pArr);
บูลีน cr = canRow (pArr);
บูลีน cminiArr = canMiniArr(pArr);
กลับ cb && cr && cminiArr;
-
//ตัดสินว่ามีองค์ประกอบเดียวกันในตาราง 3*3 ขนาดเล็กหรือไม่
บูลีนส่วนตัว canMiniArr (จุด [] [] pArr) {
int coltemp = this.col % 3;
int rowtemp = this.row % 3;
สำหรับ (int i = this.col - coltemp; i < col + (3 - coltemp); i++) {
สำหรับ (int j = this.row - rowtemp; j < แถว + (3 - rowtemp); j ++) {
ถ้า (i == this.col && j == this.row){
ดำเนินการต่อ;
}อื่น{
ถ้า(this.value == pArr[i][j].getValue()){
กลับเท็จ;
-
-
-
-
กลับเป็นจริง;
-
// ตรวจสอบว่ามีองค์ประกอบเดียวกันในคอลัมน์หรือไม่
บูลีนส่วนตัว canRow (จุด [] pArr) {
สำหรับ (int i = 0; i <9; i++) {
ถ้า (i == this.col) {
ดำเนินการต่อ;
} อื่น {
ถ้า (this.value == pArr[i][this.row].value) {//แถวเปลี่ยนแปลง คอลัมน์ยังคงไม่เปลี่ยนแปลง
กลับเท็จ;
-
-
-
กลับเป็นจริง;
-
// ตรวจสอบว่ามีองค์ประกอบเดียวกันในแถวหรือไม่
บูลีนส่วนตัว canCol (จุด [] [] pArr) {
สำหรับ (int i = 0; i <9; i++) {
ถ้า (i == this.row) {
ดำเนินการต่อ;
} อื่น {
if (this.value == pArr[this.col][i].value) {//ขอบคอลัมน์ แถวไม่เปลี่ยนแปลง
กลับเท็จ;
-
-
-
กลับเป็นจริง;
-
-
―รหัสคัดลอกโปรแกรมหลักเป็นดังนี้:
หมายเลขแพ็คเกจเกม;
นำเข้า java.io.BufferedReader;
นำเข้า java.io.IOException;
นำเข้า java.io.InputStreamReader;
นำเข้า java.util.ArrayList;
คลาสสาธารณะ Number99 {
โมฆะคงที่สาธารณะ main (String [] args) พ่น IOException {
จุด [] [] numMat = จุดใหม่ [9] [9];
ArrayList<Point> al = ArrayList ใหม่<Point>();
initNumMat(numMat,อัล);
setNum(numMat,อัล);
printMat(numMat);
-
โมฆะคงที่ส่วนตัว setNum (จุด [] [] numMat, ArrayList <Point> อัล) {
int i = 0;
อินท์เจ = 0;
ทำ{
ถ้า (numMat[i][j].getFlag()) {
for (int v = numMat[i][j].getValue()+1; v <= 9; v++) {//เพิ่มหนึ่งค่าให้กับตำแหน่งที่ส่งคืน
numMat[i][j].setValue(วี);
if (numMat[i][j].canHere(numMat)) {//ตรงตามเงื่อนไขและไม่มีข้อขัดแย้ง
numMat[i][j].changeFlag();//เปลี่ยนแฟล็กเป็นเท็จ แสดงว่าได้ตั้งค่าแล้ว
หยุดพัก;
}else{//ไม่เป็นไปตามเงื่อนไข ข้อขัดแย้ง ค่ามูลค่าจะเพิ่มขึ้นเองหนึ่งครั้ง
-
ในขณะที่ (v == 9){//ถ้า 1-9 ไม่เป็นไปตามข้อกำหนด ให้รีเซ็ตตำแหน่งหลักเป็น 0 ก่อน แล้วย้อนกลับไปหนึ่งช่อง และเพิ่มหนึ่งลงในค่าของตำแหน่งที่ส่งคืน (เมื่อตำแหน่งที่ส่งคืนคือเมื่อใด ค่าไม่ใช่ 9 รับประกันว่าตำแหน่งที่ส่งคืนไม่ใช่จุดเดิมของตารางจิ่วกง)
numMat[i][j].setValue(0);
เจ--;
ถ้า(เจ==-1){
ฉัน--;เจ=8;
-
while(al.contains(numMat[i][j])){//หากตำแหน่งที่กลับมาคือจุดเดิมของตาราง Jiugong ให้ถอยต่อไปจนกว่าจะไม่ใช่จุดของตัวเองแล้วกระโดดออกไป
เจ--;
ถ้า(เจ==-1){
ฉัน--;เจ=8;
-
-
numMat[i][j].changeFlag();//จะทำเครื่องหมาย
v = numMat[i][j].getValue();
-
-
-
เจ++;
ถ้า(จ==9){
j=0;i++;//i++ ที่นี่อาจทำให้ i เพิ่มขึ้นเป็น 9 ดังนั้นการตัดสินต่อไปนี้ต้องใช้ i!=9
-
ถ้า(i!=9){
ในขณะที่(al.contains(numMat[i][j])){
เจ++;
ถ้า(จ==9){
เจ=0;ฉัน++;
-
-
-
}ในขณะที่(i!=9);
-
โมฆะคงที่สาธารณะ initNumMat (จุด [] [] numMat, ArrayList <Point> อัล) พ่น IOException {
สำหรับ (int i = 0; i < numMat.length; i++) {
สำหรับ (int j = 0; j < numMat[i].length; j++) {
numMat[i][j] = จุดใหม่ (i, j, จริง, 0);
-
-
initNumMat2(numMat, อัล);
-
โมฆะคงที่สาธารณะ initNumMat2 (จุด [] [] numMat, ArrayList <Point> อัล) พ่น IOException {
BufferedReader br = BufferedReader ใหม่ (InputStreamReader ใหม่ (System.in));
สตริง [] p = สตริงใหม่ [3];
เส้นสตริง=null;
System.out.println("กรุณาป้อนข้อมูลจุดตามรูปแบบ (หมายเลขแถว i, หมายเลขคอลัมน์ j และค่า v), ป้อนทับ: ijv ");
ในขณะที่ ((line = br.readLine())!=null){
ถ้า(line.equals("มากกว่า"))
หยุดพัก;
p = line.trim().split(" +");
numMat[Integer.parseInt(p[0])][Integer.parseInt(p[1])].setValue(Integer.parseInt(p[2]));
numMat[Integer.parseInt(p[0])][Integer.parseInt(p[1])].changeFlag();
al.add(numMat[Integer.parseInt(p[0])][Integer.parseInt(p[1])]);
-
-
โมฆะคงที่สาธารณะ printMat (จุด [] [] numMat) {
System.out.println("--------┬---------┬---------┐");
สำหรับ (int i = 0; i < numMat.length; i++) {
สำหรับ (int j = 0; j < numMat[i].length; j++) {
ถ้า ((เจ + 1) % 3 == 0)
System.out.print(numMat[i][j].getValue() + " | ");
อื่น
System.out.print(numMat[i][j].getValue() + " ");
-
ถ้า ((i + 1) % 3 == 0)
System.out.println("/r/n--------┼---------┼---------┤");
อื่น
System.out.println();
-
-
-
--- รันโปรแกรม
โปรดป้อนข้อมูลจุดตามรูปแบบ (หมายเลขแถว i หมายเลขคอลัมน์ j และค่า v) และป้อนทับ: ijv เมื่อป้อน
0 0 8
1 2 3
1 3 6
2 1 7
2 4 9
2 6 2
3 1 5
3 5 7
4 4 4
4 5 5
4 6 7
5 3 1
5 7 3
6 2 1
6 7 6
6 8 8
7 2 8
7 3 5
7 7 1
8 1 9
8 6 4
เกิน
--
8 1 2 |. 7 5 3 |
9 4 3 |. 6 8 2 |
6 7 5 |. 4 9 1 |
--
1 5 4 |. 2 3 7 |
3 6 9 |. 8 4 5 |
2 8 7 |. 1 6 9 |
--
5 2 1 |. 9 7 4 |
4 3 8 |. 5 2 6 |
7 9 6 |. 3 1 8 |
--