晕,一维的好麻烦,这个也是碰巧前两天刚写好的,你看着自己修改下
#include <stdio.h>
typedef struct
{
int line
int row
int num
}Node
int main()
{
/*
int a[9][9]={
{4,0,3,6,0,0,0,0,0},
{0,0,0,0,0,1,0,2,4},
{0,1,0,0,4,0,5,0,0},
{0,0,0,9,0,4,0,6,0},
{3,0,2,0,0,0,4,0,9},
{0,7,4,1,0,3,0,0,0},
{0,0,1,0,9,0,0,4,0},
{2,4,0,3,0,0,0,0,0},
{0,0,0,4,0,8,2,0,7}}
*/
int a[9][9]={
{0,0,0,8,0,0,0,6,0},
{8,7,0,0,0,0,0,0,0},
{2,9,0,0,4,1,0,0,5},
{0,0,5,7,0,0,0,0,9},
{0,2,0,0,0,0,0,1,0},
{9,0,0,0,0,4,3,0,0},
{7,0,0,6,1,0,0,9,8},
{0,0,0,0,0,0,0,5,2},
{0,6,0,0,0,9,0,0,0}}
/*
int a[9][9]={
{0,2,0,0,6,0,0,0,0},
{0,9,0,4,0,5,1,3,0},
{0,0,8,7,0,0,0,0,5},
{6,0,0,3,0,0,4,0,0},
{0,0,0,9,0,6,0,0,0},
{0,0,7,0,0,1,0,0,3},
{4,0,0,0,0,7,3,0,0},
{0,8,5,2,0,4,0,7,0},
{0,0,0,0,9,0,0,1,0}}
*/
/*
int a[9][9]={
{0,0,3,0,2,0,0,0,6},
{0,0,2,0,9,0,0,0,4},
{7,0,0,8,0,0,2,0,3},
{0,8,0,0,7,0,5,0,0},
{0,7,0,1,0,6,0,3,0},
{0,0,0,2,0,0,0,9,0},
{4,0,6,0,0,8,0,0,5},
{6,0,0,0,4,0,3,0,0},
{9,0,0,0,1,0,7,0,0}}
*/
int i,j,n,en,flag,y,k=0,x,qu,p,q
Node b[70]
for(i=0i<9i++)
{
for(j=0j<9j++)
{
if(!a[i][j])
{
b[k].line=i
b[k].row=j
b[k].num=0
k+=1
}
}
}
en=k
/*从b[0]开始试,若b[k].num>9,则k-1,否则k+1*/
for(k=0k<en)
{
++b[k].num
i=b[k].line
j=b[k].row
a[i][j]=b[k].num
n=0
while(n<9&&b[k].num<=9)
{
if(n==i)
{
for(y=0y<9y++)
{
if(y==j)
continue
if(a[n][y]==a[i][j])
flag=1
}
}
else if(n==j)
{
for(y=0y<9y++)
{
if(y==i)
continue
if(a[y][n]==a[i][j])
flag=1
}
}
/*判断同一块中有没有相同值*/
qu=3*(i/3)+j/3
switch(qu)
{
case 0:x=0
y=0
break
case 1:x=0
y=3
break
case 2:x=0
y=6
break
case 3:x=3
y=0
break
case 4:x=3
y=3
break
case 5:x=3
y=6
break
case 6:x=6
y=0
break
case 7:x=6
y=3
break
default :x=6
y=6
break
}
p=x
q=y
for(x<p+3x++)
{
for(y<q+3y++)
{
if(x==i&&y==j)
continue
if(a[x][y]==a[i][j])
{
flag=1
break
}
}
if(flag==1)
break
}
if(flag==1)
{
a[i][j]=++b[k].num
flag=0
n=0
continue
}
n++
}
if(b[k].num>9)
{
a[i][j]=b[k].num=0
k--
if(k<0)
{
printf("error!\r\n")
return -1
}
}
else
k++
}
for(i=0i<9i++)
{
for(j=0j<9j++)
{
printf("%d",a[i][j])
}
printf("\r\n")
}
return 1
}
#include <windows.h>#include <stdio.h>
#include <time.h>
char sd[81]
bool isok = false
//显示数独
void show()
{
if (isok) puts("求解完成")
else puts("初始化完成")
for (int i = 0i <81i++)
{
putchar(sd[i] + '0')
if ((i + 1) % 9 == 0) putchar('\n')
}
putchar('\n')
}
//读取数独
bool Init()
{
FILE *fp = fopen("in.txt", "rb")
if (fp == NULL) return false
fread(sd, 81, 1, fp)
fclose(fp)
for (int i = 0i <81i++)
{
if (sd[i] >= '1' &&sd[i] <= '9') sd[i] -= '0'
else sd[i] = 0
}
show()
return true
}
//递归解决数独
void force(int k)
{
if (isok) return
if (!sd[k])
{
for (int m = 1m <= 9m++)
{
bool mm = true
for (int n = 0n <9n++)
{
if ((m == sd[k/27*27+(k%9/3)*3+n+n/3*6]) || (m == sd[9*n+k%9]) || (m == sd[k/9*9+n]))
{
mm = false
break
}
}
if (mm)
{
sd[k] = m
if (k == 80)
{
isok = true
show()
return
}
force(k + 1)
}
}
sd[k] = 0
}
else
{
if (k == 80)
{
isok = true
show()
return
}
force(k + 1)
}
}
int main()
{
system("CLS")
if (Init())
{
double start = clock()
force(0)
printf("耗时%.0fms", clock() - start)
}
else puts("初始化错误")
getchar()
}
单向扫看法:在第一个例子中,我们注意看一下第2宫。我们知道,每个宫内必须包含数字9,第1宫以及第3宫中都包含数字9,并且第1宫的9位于第3行。
第3宫的9位于第2行,这也就意味着第2宫的9不能在第2行和第3行,所有第2宫的9只能放置在第2宫第1行的空格内。
2.双向扫看法:同样的技巧也可以扩展到相互垂直的行与列中。让我们想一下第3宫中1应该放在哪里。在这个例子中,第1行以及第2行已经有1了,那么第3宫中只有底部的俩个空格可以填1。不过,方格g4已经有1了,所有第g列不能再有1。
所以i3是该宫唯一符合条件填上数字1的地方。
3.寻找候选法:通常地,一个方格只能有一个数字的可能性,因为剩下的其他8个数字都已经被相关的行列宫所排除了。我们看一下下面例子中b4这个方格。b4所在的宫中已经存在了数字3,4,7,8,1和6位于同一行,5和9位于同一列,排除上述所有数字,b4只能填上2。
4数字排除法:排除法是一个相对繁杂的寻找数字的方法。我们可以从c8中的1间接推出e7和e9必须包含数字1,不管这个1在哪个方格,我们可以确认的是,第e列的数字1肯定在第8宫内,所以第2宫内中间这一列就不可能存在数字1。因此,第2宫的数字一必须填在d2处。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)