最开始的时候,先考虑是否为最后一位,忽视了最后一位是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"); }
时间: 2024-10-13 20:47:48