题目链接sicily 1317
这题咋一看以为不简单,因为第一感觉是时间复杂度很大,可想想写起来应该不难,于是飞快的写了个dfs。 结果是证明了我的感觉,超时了。确实是写起来容易的代码来对付时间复杂度很大很大的是会超时的。 只能做些优化了。看了别人的做法,也想到了之前马的周游一样的优化方法。从能够填写的数字个数最少的位置开始 深搜。原因是产生的树上端都是小,然后搜到下面的位置的话,一旦不符合很快就返回,结束掉,不会继续。避免说树的上端 很大,下端很小,结果即使下端返回了,上端要循环的次数还是很多。
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int grid[9][9];
bool cols[9][10];
bool rows[9][10];
bool subgrid[9][10];
int firstAns[9][9]; //first solution
int ansCnt;
int puzzle[82];
int cnt[82];
void dfs()
{
int x, y, j;
int min = 81;
for (j = 0; puzzle[j] != 88; ++j) {
if (cnt[j] < cnt[min] && grid[puzzle[j]/9][puzzle[j]%9] == 0)
min = j;
}
if (min == 81) {
++ansCnt;
if (ansCnt == 1) {
for (y = 0; y < 9; ++y)
for (x = 0; x < 9; ++x)
firstAns[y][x] = grid[y][x];
}
return ;
}
x = puzzle[min]%9;
y = puzzle[min]/9;
for (j = 0; j < 9; j++) {
cnt[x + j * 9]--;
cnt[y * 9 + j]--;
}
int gridId = x/3 + y/3 * 3;
for (int i = 1; i < 10; ++i) {
if (!cols[x][i] && !rows[y][i] && !subgrid[gridId][i]) {
cols[x][i] = true;
rows[y][i] = true;
subgrid[gridId][i] = true;
grid[y][x] = i;
dfs();
cols[x][i] = false;
rows[y][i] = false;
subgrid[gridId][i] = false;
grid[y][x] = 0;
}
}
for (j = 0; j < 9; j++) {
cnt[x + j * 9]++;
cnt[y * 9 + j]++;
}
}
void init()
{
ansCnt = 0;
memset(cols, false, sizeof(cols));
memset(rows, false, sizeof(rows));
memset(subgrid, false, sizeof(subgrid));
memset(cnt, 0, sizeof(cnt));
}
void find()
{
int k = 0;
for (int i = 0; puzzle[i] != 88 ; i++) {
int x = puzzle[i]%9;
int y = puzzle[i]/9;
int gridId = x/3 + y/3 * 3;
for (int j = 1; j < 10; j++)
if (!cols[x][j] && !rows[y][j] && !subgrid[gridId][j])
cnt[i]++;
}
cnt[81] = 100;
}
int main()
{
// freopen("input.txt","r",stdin);
int t, num = 1;
scanf("%d",&t);
getchar();
while (t--)
{
init();
int x, y;
//input
int index = 0;
for (y = 0; y < 9; ++y) {
char in[10];
gets(in);
for (x = 0; x < 9; ++x) {
if (in[x] == '_') {
grid[y][x] = 0;
puzzle[index++] = x + y*9;
}
else {
int dig = in[x] - '0';
int gridId = x/3 + y/3 * 3;
grid[y][x] = dig;
cols[x][dig] = true;
rows[y][dig] = true;
subgrid[gridId][dig] = true;
}
}
//printf("\n");
}
puzzle[index] = 88;
find();
dfs();
//output
printf("Puzzle %d ",num++);
if (ansCnt == 0)
printf("has no solution\n");
else if (ansCnt > 1)
printf("has %d solutions\n",ansCnt);
else {
printf("solution is\n");
for (y = 0; y < 9; ++y) {
for (x = 0; x < 9; ++x)
printf("%d",firstAns[y][x]);
printf("\n");
}
}
if (t != 0)
printf("\n");
}
}