C语言回溯法九宫格数独问题

来源:互联网 发布:乎的用法 编辑:程序博客网 时间:2024/06/04 19:37

Problem H

数独游戏

时限:1000ms 内存限制:10000K 总时限:3000ms

描述:

数独游戏规则
在9阶方阵中,包含了81个小格(九列九行),其中又再分成九个小正方形(称为宫),每宫有九小格。
游戏刚开始时,盘面上有些小格已经填了数字(称为初盘),游戏者要在空白的小格中填入1到9的数字,
使得最后每行、每列、每宫都不出现重复的数字,而且每一个游戏都只有一个唯一的解答(称为终盘)。

输入:

一个9*9的矩阵,0表示该位置是空白。

输出:

一个9*9的矩阵,格式与输入类似。

输入样例:

900050060020070100300102040703800529000345000516009403050208006007090010030010004

输出样例:

971453268428976135365182947743861529892345671516729483154238796687594312

239617854

#include<stdio.h>#include<string.h>int a[9][9];void search(int n);int  canplace(int n,int i);void output();int main(){char b[9][10];int q,j;for(q=0;q<9;q++){for(j=0;j<=9;j++)//由于输入数据之间不含空格,所以只能用字符串存起来再转换成整型数组{scanf("%c",&b[q][j]);if(b[q][j]!='\n')//换行时字符串会自动读取换行符,所以应该考虑到这种情况a[q][j]=b[q][j]-'0';//字符型数组转换成整型数组}}search(0);//回溯法求解return 0;} void search(int n){int i;if(n==81)output();else if(a[n/9][n%9]!=0)search(n+1);若该位置上已有数字,则跳转至下一个位置else if(a[n/9][n%9]==0)for(i=1;i<=9;i++){ if(canplace(n,i))//判断该位置上能否放置数字i,若可以为其赋值,跳转至下一位置 { a[n/9][n%9]=i;search(n+1); } a[n/9][n%9]=0;若若找不到可以满足条件的数放置在该位置,还原它本来的值,回溯寻找下一组可能的解,每次调用完之后都需要让它返回与原来的值}}}int  canplace(int n,int i){int j,k,flag=1;for(j=0;j<=8;j++)//判断该列上是否有该数字{if(a[n/9][j]==i){flag=0;break;}}if(flag==1){for(j=0;j<=8;j++)判断该行是否有该数字{if(a[j][n%9]==i){flag=0;break;    }}    }    if(flag==1)//判断其所在的小九宫格里是否有该数字{for(j=(n/9/3)*3;j<(n/9/3)*3+3;j++){for(k=(n%9/3)*3;k<(n%9/3)*3+3;k++){if(a[j][k]==i){flag=0;break;}if(flag==0)break;}}    }return flag;}void output()//输出数组{int i,j;for(i=0;i<9;i++){for(j=0;j<9;j++){printf("%d",a[i][j]);}printf("\n");} }