#include<stdio.h>
#include<string.h>
int a[9][9]
int checkAnswer()
{int i,j,s,b[10],i1,j1
for(i=0i<9i++)
{memset(b,0,sizeof(b))
for(j=0j<9j++)
b[a[i][j]]=1
for(j=s=0j<10j++)
s+=b[j]
if(s-9)return 0
}
for(i=0i<9i++)
{memset(b,0,sizeof(b))
for(j=0j<9j++)
b[a[j][i]]=1
for(j=s=0j<10j++)
s+=b[j]
if(s-9)return 0
}
for(i=0i<9i+=3)
for(j=0j<9j+=3)
{memset(b,0,sizeof(b))
for(i1=0i1<3i1++)
for(j1=0j1<3j1++)
b[a[i+i1][j+j1]]=1
for(j1=s=0j1<10j1++)
s+=b[j1]
if(s-9)return 0
}
return 1
}
int main()
{int t,i,j
FILE *fp
if((fp=fopen("d:\\0.txt","r"))==NULL)
{printf("File open error!\n")
return 0
}
fscanf(fp,"%d",&t)
while(t--)
{for(i=0i<9i++)
for(j=0j<9j++)
fscanf(fp,"%d",&a[i][j])
printf("%s\n",checkAnswer()?"Yeah!":"Oh,No!")
}
fclose(fp)
return 0
}
#include<stdio.h>int num[9][9], xy[9][9]
int check(int x, int y) {
int i, m, n
for(i = 0 i < 9 i++)
if ((xy[x][y] == xy[i][y]&&i != x)||(xy[x][y] == xy[x][i]&&i != y))
return 0
for(i = 0, m = x / 3 * 3, n = y / 3 * 3 i < 9 i++)
if (xy[x][y] == xy[m + i / 3][n + i % 3]&&m + i / 3 != x&&n + i % 3 != y)
return 0
return 1
}
void search(int x, int y) {
if (x == 9)
for(x = 0 x < 9 x++) {
for(y = 0 y < 9 y++)
printf("%d ", xy[x][y])
printf("\n")
}
else if (num[x][y])
search(x + (y + 1) / 9, (y + 1) % 9)
else
for(xy[x][y] = 1 xy[x][y] <= 9 xy[x][y]++)
if (check(x, y))
search(x + (y + 1) / 9, (y + 1) % 9)
return
}
int main() {
int i, j
for(i = 0 i < 9 i++)
for(j = 0 j < 9 j++) {
scanf("%d", &num[i][j])
xy[i][j] = num[i][j]
}
search(0, 0)
return 0
}
输入为9行9列整数,已知的整数填写对应的数字,尚待计算的未知数字填写0。
该代码的思路很简单,就是从第一行第一列开始依次填入数字,检查是否是在同一行、同一列、同一宫有没有填入重复数字,如果没有就继续填入下一个数字,如果有就返回。
虽然效率稍低,但原理简单、表述直白、易于理解,更有效率的代码是使用十字链表完成,如有兴趣可继续深入
给,注释改一改,有台湾风格了:#include <stdio.h >
#include <stdlib.h >
int sudoku[81] // 数独题目阵列
int tempNum[81] // 上一次填数位置
int tempSp= 0 // 上一次填数位置指标
int startH[81] // 列位置的起点
int startV[81] // 行位置的起点
int startB[81] // 九宫格位置的起点
int addH[9] // 列位置的加值
int addV[9] // 行位置的加值
int addB[9] // 九宫格位置的加值
void init() {
// 参数设定(设定这些参数之后,无论检查行、列、九宫格都方便多了)
int i
for(i=0i<81i++) {
startH[i]= i/9* 9 // 列位置的起点
startV[i]= i% 9 // 行位置的起点
startB[i]= ((i/9)/3)*27+ ((i%9)/3)*3 // 九宫格位置的起点
}
for(i=0i<9i++) {
addH[i]= i // 列位置的加值
addV[i]= i*9 // 行位置的加值
addB[i]= (i/3)*9+ (i%3) // 九宫格位置的加值
}
}
void printSudoku(int *prn) {
// 印出数独题目(阵列内容)
int i
for(i=0i<81i++) {
printf( "%2d", prn[i])
if(i%9==8) printf("\n")
}
}
int getNextBlank(int sp) {
// 取得下一个空白的位置
do {
sp++
} while(sp<81 &&sudoku[sp]>0)
return(sp)
}
int check1(int sp, int start, int *addnum) {
// 检查指定的行、列、九宫格有没有相同的数字,若有传回 1
int fg= 0, i, sp1
for(i=0i<9i++) {
sp1= start+ addnum[i]
if(sp!=sp1 &&sudoku[sp]==sudoku[sp1]) fg++
}
return(fg)
}
int check(int sp) {
// 检查同行、列、九宫格有没有相同的数字,若有传回 1
int fg= 0
if(!fg) fg= check1(sp, startH[sp], addH) // 检查同列有没有相同的数字
if(!fg) fg= check1(sp, startV[sp], addV) // 检查同行有没有相同的数字
if(!fg) fg= check1(sp, startB[sp], addB) // 检查同九宫格有没有相同的数字
return(fg)
}
void push(int sp) {
// 将指定的位置放入堆叠中
tempNum[tempSp++]= sp
}
int pop() {
// 取出堆叠中的上一个位置
if(tempSp<0) return(-1)
else return(tempNum[--tempSp])
}
void tryAns() {
// 测试求解
int sp=getNextBlank(-1) // 取得第一个空白的位置开始填入数字
do {
sudoku[sp]++ // 将本位置数字加 1
if(sudoku[sp]>9) { // 如果本位置的数字已大於 9 时则回到上一个位置继续测试
sudoku[sp]= 0
sp= pop()
} else {
if(check(sp)==0) { // 如果同行、列、九宫格都没有相同的数字,则到下一个空白处继续
push(sp) // 当然,如果发现有相同的数字时,就需把原位置的数字加 1(所以本处什麼都不做)
sp= getNextBlank(sp)
}
}
} while(sp>=0 &&sp<81)
}
int main(int argc, char *argv[]) {
int j
printf( "----------\n")
printSudoku(sudoku)
init() // 参数设定
tryAns() // 测试求解
printf( "----------\n")
printSudoku(sudoku)
printf( "----------\n")
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)