题意
从0~9填入如图所示(图一)的十个空格中,要求:不存在相邻的两数在格中相邻,格中相邻的情况为(上下、左右、对角线)。
解题思路
通过深度优先搜索构造符合条件的组合,然后判断组合中数是否符合题目要求。在看到图一时,我也很是无语,为啥长成这样?能不能规规矩矩的?为了便于检测,在此已将原格子补充完成如下图所示(图二) ,并在相应位置填入,不与0~9中任意数相邻的数(这样仍旧保证添加的两格不影响结果)。
具体实现
package lanqiao;
import java.util.*;
public class TestFillNumber {
public static void main(String[] args) {
init();
DFS(0);
System.out.println(count);
}
/**
* 数据长度
*/
final static int LEN = 10;
/**
* 访问控制标记
*/
static boolean[] vis;
/**
* 组合值
*/
static StringBuffer aimValue = new StringBuffer();
/**
* 数据规模
*/
static int m = 3;
static int n = 4;
/**
* 固定值
*/
static String trail = new String("N");
/**
* 方向控制
*/
static int[] dirx = {-1, 1, 0, 0, -1, 1, -1, 1};
static int[] diry = {0, 0, -1, 1, -1, 1, 1, -1};
/**
* 符合条件统计
*/
static int count;
/**
* 检测串
*/
static StringBuffer other;
/**
* 初始化
*/
public static void init() {
vis = new boolean[LEN];
Arrays.fill(vis, false);
other = new StringBuffer();
count = 0;
}
/**
* 深度优先搜索
*
* @param t
*/
public static void DFS(int t) {
// 搜索结束条件
if (t == LEN) {
//判断条件
if (isCorrect()) {
System.out.println(other);
count++;
}
} else {
for (int i = 0; i < LEN; i++) {
if (!vis[i]) {
vis[i] = true;
aimValue.append((char) (i + 'A'));
DFS(t + 1);
aimValue.delete(t, t + 1);
vis[i] = false;
}
}
}
}
private static boolean isCorrect() {
//默认情况下,已构造字符串符合要求
boolean flag = true;
char ch;
int index1;
int index2;
//相邻点的坐标
int nx, ny;
//取得的相邻两数
int n1, n2;
//将已构造的数据复制至一个新的字符串other中
other = new StringBuffer(aimValue.toString());
//在新的字符串的首和尾增加一个字符,该字符不与A-J中的任意一个字符相连
other.insert(0, trail);
other.append(trail);
//检测每一个字符是否与相邻字符相连
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
index1 = i * n + j;
ch = other.charAt(index1);
n1 = ch - 'A';
for (int k = 0; k < 8; k++) {
nx = i + dirx[k];
ny = j + diry[k];
// 边界判断
if ((nx >= 0 && nx < m) && (ny >= 0 && ny < n)) {
index2 = nx * n + ny;
ch = other.charAt(index2);
n2 = ch - 'A';
//相邻数字的差的绝对值为1
if (1 == Math.abs(n1 - n2)) {
flag = false;
break;
}
}
}
if (!flag) {
break;
}
}
if (!flag) {
break;
}
}
return flag;
}
}