sincerit 算法竞赛宝典-数独游戏(深搜)

【题目描述】数独游戏

“我陪你玩这个数独游戏已经整整三天了,你到底什么时候给我上古神器?”修罗王忍不住问。

“这人生啊,急也好,慢也好,目标总能达到,何不让自己静下心来,慢慢欣赏一下沿途的风景?”上古神器的守护者悠悠道。

修罗王悻悻道:“如果玩这个没有赌注的话,我还真信你的话了,就三天工夫,你都把我的魔法石赢去一大半了。”

已知9×9的方阵,有些格子填有1-9的数字,有的格子则是空白。你的任务是完成这个方阵,使得每一行、每一列以及每一个小九宫格中的数字都刚好是1~9。

如图所示,该例子中左图是开始时的方阵状态,右图为完成后的样子。
sincerit 算法竞赛宝典-数独游戏(深搜)_第1张图片
【输入格式】
9行9列的方阵状态,0代表空格。
【输出格式】
输出完成后的方阵状态,每一个小九宫格以空格分隔。行为三个空格,列为一个空格。
【输入样例】
0 6 0 1 0 4 0 5 0
0 0 8 3 0 5 6 0 0
2 0 0 0 0 0 0 0 1
8 0 0 4 0 7 0 0 6
0 0 6 0 0 0 3 0 0
7 0 0 9 0 1 0 0 4
5 0 0 0 0 0 0 0 2
0 0 7 2 0 6 9 0 0
0 4 0 5 0 8 0 7 0
【输出样例】
9 6 3 1 7 4 2 5 8
1 7 8 3 2 5 6 4 9
2 5 4 6 8 9 7 3 1

8 2 1 4 3 7 5 9 6
4 9 6 8 5 2 3 1 7
7 3 5 9 6 1 8 2 4

5 8 9 7 1 3 4 6 2
3 1 7 2 4 6 9 8 5
6 4 2 5 9 8 1 7 3

设step表示当前位置,坐标可以用x = step / 9, y = step % 9;
除了求出坐标外还需要求出该位置所在的宫 i = x / 3 * 3, j = y / 3 * 3;得到所在宫的第一个坐标

#include 
#include 
int graph[10][10];
int visx[10][10]; // 9行每一行的9个数 
int visy[10][10]; // 9列每一列的9个数 
int check(int x, int y, int num) { 
  int xi = x / 3 * 3, yj = y / 3 * 3; // 得到宫的坐标
  for (int i = xi; i < xi+3; i++) {
    for (int j = yj; j < yj+3; j++) {
      if (graph[i][j] == num) return 0;
    }
  }
  return 1;
} 
void DFS(int step) {
  if (step >= 81) {
    for (int i = 0; i < 9; i++) {
      for (int j = 0; j < 9; j++) printf("%-2d", graph[i][j]);
      printf("\n");
    }
    return;
  }
  int x = step / 9, y = step % 9; // 得到当前坐标 
  if (graph[x][y] != 0) DFS(step+1); // 不能放到循环里面去
  /*
    放到循环里面的时候回溯时就会出问题得不到答案 
  */ 
  for (int i = 1; i <= 9; i++) {
    if (graph[x][y] == 0) { // 这个条件是必要的,因为有这么一种情况 0x0后面一个空格没法填其他的数了要回溯了,到达填了数x的空格,如果不限制的话会改掉这个数,就出错了
      if (!visx[x][i] && !visy[y][i] && check(x, y, i)) {
        graph[x][y] = i;
        visx[x][i] = 1;
        visy[y][i] = 1;
        DFS(step+1);
        visx[x][i] = 0;
        visy[y][i] = 0;
        graph[x][y] = 0;
      }
    }
  }
} 

int main() {
  int num;
  memset(visx, 0, sizeof(visx));
  memset(visy, 0, sizeof(visy));
  for (int i = 0; i < 9; i++) {
    for (int j = 0; j < 9; j++) {
      scanf("%d", &num);
      if (num != 0) {
        visx[i][num] = 1;
        visy[j][num] = 1;
      }
      graph[i][j] = num;
    }
  }
  DFS(0);
  return 0;
}

你可能感兴趣的:(搜索)