标签:
最开始的时候,先考虑是否为最后一位,忽视了最后一位是0的可能,
也忽略了,拷贝数组再处理和递归后恢复现场再进入循环,弄了好长时间
另外x行y列这个表述太差劲了,应该换成i行j列比较好些
#include<stdio.h>
int count=0;// 统计有多少种结果
void scan(int temp[][9]);
int arrange(int temp[][9],int x,int y);//组织数独
int check(int temp[][9],int x,int y,int number);//判断是否可以填入该数字
void print(int temp[][9]);
void plus( int *ptrx ,int *ptry);//进位
void minus( int *ptrx ,int *ptry);//退位
int main() {
int sudoku[9][9]= {0};
scan(sudoku);
arrange(sudoku,0,0);
if(count==0)
printf("此数独无解");
return 0;
}
int arrange(int sudoku[][9],int x,int y) {
int i,j;
int temp[9][9];
for(i=0; i<=8; i++) {
for(j=0; j<=8; j++) {
temp[i][j]=sudoku[i][j];//拷贝一份
}
}
if(temp[x][y]==0) {//如果为零,尝试填入
for(i=1; i<=9; i++) {
if( check(temp,x,y,i)) {
temp[x][y]=i;//可以填入就填入
plus(&x,&y);//进位
arrange(temp,x,y);//递归
minus(&x,&y);//恢复现场 ,准备下一次循环
temp[x][y]=0;
}
}
} else {
if(x==9&&y==0) {//最后一位再加一的结果
count++;
print(temp);
} else {
plus(&x,&y);//如果不是最后一位,进位
arrange(temp,x,y);
}
}
}
void scan(int temp[][9]) {
int i,j;
for(i=0; i<=8; i++) {
for(j=0; j<=8; j++) {
scanf("%d",&temp[i][j]);
}
}
}
int check(int temp[][9],int x,int y,int number) {
int i,j,m,n;
for(i=0; i<=8; i++) {
if(temp[i][y]==number)
return 0;
}
for(i=0; i<=8; i++) {
if(temp[x][i]==number)
return 0;
}
//判断九宫格是否符合
if(x==6||x==7||x==8)
m=6;//减轻了乘除法的负担,不知道作用多大
if(x==3||x==4||x==5)
m=3;
if(x==0||x==1||x==2)
m=0;
if(y==6||y==7||y==8)
n=6;
if(y==3||y==4||y==5)
n=3;
if(y==0||y==1||y==2)
n=0;
for(i=m; i<m+3; i++) {
for(j=n; j<n+3; j++) {
if(temp[i][j]==number)
return 0;
}
}
return 1;
}
void plus( int *ptrx ,int *ptry) {
if(*ptry==8) {
(*ptrx)++;
*ptry=0;
} else {
(*ptry)++;
}
}
void minus( int *ptrx ,int *ptry) {
if(*ptry==0) {
(*ptrx)--;
*ptry=8;
} else {
(*ptry)--;
}
}
void print(int a[][9]) {
int i,j;
printf("Case %d: \n",count);
for(i=0; i<=8; i++) {
for(j=0; j<=8; j++) {
printf("%d ",a[i][j]);
}
printf("\n");
}
printf("\n");
}
标签:
原文地址:http://www.cnblogs.com/lhy1024/p/5205421.html