TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
// Square.java
/**
* 测试程序 计算数独里面的9宫格
*
* @author 惜缘
* @input base[][] 数组
*/
public class Square {
// 声明保存结果的数组
int array[][];
// 用户基础数据
// static int base[][]=new int[9][9];
static int base[][] = {
{ 1, 0, 0, 2, 0, 0, 6, 0, 9 },
{ 2, 0, 9, 0, 1, 6, 0, 5, 0 },
{ 0, 0, 6, 0, 3, 7, 8, 0, 0 },
{ 0, 0, 8, 0, 0, 2, 0, 0, 6 },
{ 7, 0, 3, 0, 0, 9, 1, 0, 2 },
{ 6, 0, 0, 0, 4, 8, 9, 0, 0 },
{ 0, 0, 4, 6, 9, 0, 7, 0, 0 },
{ 0, 6, 0, 7, 0, 0, 2, 0, 4 },
{ 9, 0, 0, 0, 0, 3, 0, 0, 8 } };
boolean forward = true; // 前进
/**
* @param args
*/
public static void main(String[] args) {
Square s = new Square();
// 检测基础数据是否合法
for (int i = 0; i < base.length; i++) {
for (int j = 0; j < base.length; j++) {
if (!s.test(base, j, i, base[j])) {
System.out.println("Error! i=" + i + " j=" + j);
return;
}
}
}
System.out.println("ok");
// 求解
s.resolveSquare(9);
// 输出结果
s.show();
}
/**
* 求解维数为 n 问题域
*/
public void resolveSquare(int n) {
// 目前仅支持 n==9 的操作
if (n != 9) {
return;
}
// 进行初始化操作
array = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
array[j] = base[j];
}
}
// 求解
int start = 1; // 从1开始
int i = 0, j = 0; // 下标初始值
int step = 0; // 前进步数
int total = n * n;
labelwhile: while (step < total) {
if (base[j] != 0) {
if (forward) { // 前进
step++; // 当前数为固定数 前进一步
// 修改相应的坐标值
if (j == (n - 1)) {
// 当前列已经到了最后一列
j = 0; // 横向归0
i++; // 纵向加1
} else {
j++; // 横向加1
}
continue labelwhile;
} else { // 后退
step--; // 当前数为固定数 后退一步
// 修改相应的坐标值
if (j == 0) {
// 当前列为第一列
j = n - 1; // 横向置为n-1
i--; // 纵向减1
} else {
j--; // 横向减1
}
continue labelwhile;
}
}
start = array[j] + 1; // 预赋值为当前值 加 1
if (start > n) { // 数值不合法 需回退
// 如果当前值大于维域 n (此处为9) 或 不合法时 则回退
array[j] = 0;
if (i != 0 && j == 0) { // 位于第一列
i = i - 1; // 纵向退一行
j = n - 1; // 横向置为最后一列
} else {
j = j - 1; // 横向退一列
}
if (i < 0) {
System.out.println("此题无解 step:" + step);
return;
}
step--;
forward = false; // 后退
continue labelwhile; // 进入下一轮检测
}
if (!test(array, j, i, start)) {
array[j] = start; // 修改当前坐标值
continue labelwhile; // 进入下一轮检测
}// 检测完毕
// 通过检测 前进一步
array[j] = start; // 修改当前坐标值
step++; // 通过检测 前进一步
// 修改相应的坐标值
if (j == (n - 1)) {
// 当前列已经到了最后一列
j = 0; // 横向归0
i++; // 纵向加1
} else {
j++;
}
forward = true; // 前进
// 进入下一轮循环
}// end while
}
/**
* 检测当前值是否合法
*/
public boolean test(int arr[][], int cur_x, int cur_y, int val) {
// 检测传入参数是否合法
if (arr == null) {
return false;
}
int len_y = arr.length; // 数组纵高
int len_x = arr[0].length; // 数组横宽
if (cur_x < 0 || cur_x >= len_x || cur_y < 0 || cur_y >= len_y) {
return false;
}
// 默认是合法
boolean flag = true;
// 横向检测 从左到右
for (int i = 0; i < len_x; i++) {
if ((i != cur_x) && arr[cur_y] != 0 && arr[cur_y] == val) {
return false; // 如果有重复值 则返回false
}
}
// 纵向检测 从上到下
for (int j = 0; j < len_y; j++) {
if ((j != cur_y) && arr[j][cur_x] != 0 && arr[j][cur_x] == val) {
return false; // 纵向有冲突
}
}
// 如果 n==9 则计算小方格的合法性
// 计算小方格的起始坐标
if (len_x == 9 && len_y == 9) {
int s_i = (cur_y / 3) * 3; // 起始行
int s_j = (cur_x / 3) * 3; // 起始列
for (int i = s_i; i < s_i + 3; i++) {
for (int j = s_j; j < s_j + 3; j++) {
if ((j != cur_x) && (i != cur_y) && arr[j] != 0
&& arr[j] == val) {
return false; // 纵向有冲突
}
}
}
}// end if
return flag;
}
/**
* 输出结果
*/
public void printResult(int arr[][]) {
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr.length; j++) {
System.out.print(arr[j] + " ");
}
System.out.println(); // 换行
}
}
/**
* 调用printResult(...)来输出结果
*/
public void show() {
printResult(array);
}
}
/* 输出结果
ok
1 8 7 2 5 4 6 3 9
2 3 9 8 1 6 4 5 7
4 5 6 9 3 7 8 2 1
5 9 8 1 7 2 3 4 6
7 4 3 5 6 9 1 8 2
6 1 2 3 4 8 9 7 5
8 2 4 6 9 5 7 1 3
3 6 5 7 8 1 2 9 4
9 7 1 4 2 3 5 6 8
*/
源码下载:http://file.javaxxz.com/2014/11/10/000220390.zip |
|