POJ2676 Sudoku

/*

题目:

       填充数独游戏

分析:

       先从后面开始搜,也就是从第八十个开始搜

       1、如果一个小的方格内已经包含了非零的数,则继续向下搜

       2、如果一个小的方格内是一个零数,也就是还没有放入相应的数,则对其从零到九开始尝试

       3、对每一个数的尝试,检查其合法性:在其所在的3*3方格内是否合适;在此行是否合适,在此列是否合适

       4、如果经过以上条件可以的话那么这个数字就可以放在此小方格上,然后继续进行搜索。

 

*/

#include <iostream>

#include <cstring>

#include <string>

using namespace std;

int a[10][10];

int can(int i,int x,int y)

{     //i:尝试填下的数,x:行数,y:列数

       for(int j=1;j<=9;j++)            //计算同行或同列是否已有此数

              if(a[x][j]==i||a[j][y]==i)

                     return 0;

 

       int r = (x-1)/3;       //计算同一方框内的行序号

       int l = (y-1)/3;       //计算同一方框内的列序号

       for(int j=r*3+1;j<=r*3+3;j++)

              for(int k=l*3+1;k<=l*3+3;k++)

                     if(a[j][k]==i)

                            return 0;

       return 1;

}

int dfs(int n)

{     //n:剩下未填的数

       if(n==0)  //如果剩下为填的数为0,证明全部填好,返回1

              return 1;

       int x = (n+8)/9;      //计算行号

       int y = n%9;          //计算列号

       if(y==0)                //如果列号为0,置9

              y = 9;

       if(a[x][y])                    //已经给出数了

       {

              if(dfs(n-1))     //如果剩下的能够安置好,返回1,否则返回0

                     return 1;

       }

       else                       //如果没有给出

       {

              for(int i=1;i<=9;i++)     //从1到9尝试填充

              {

                     if(can(i,x,y))          //如果可以填下此数

                     {

                            a[x][y] = i;     //标记此格

                            if(dfs(n-1))     //如果剩下的数能安置好,则返回1

                                   return 1;

                            a[x][y] = 0;    //剩下的数不能安置好,返回0且把此格标记空格0

                     }

              }

       }

       return 0;

}

int main()

{

       freopen("sum.in","r",stdin);

       freopen("sum.out","w",stdout);

       int n;

       cin>>n;

       while(n--)

       {

              memset(a,0,sizeof(a));

              for(int i=1;i<=9;i++)

              {

                     string s;

                     cin>>s;

                     for(int j=1;j<=9;j++)

                            a[i][j] = s[j-1]-'0';//字符转换数字

              }

              if(dfs(81))

              {

                     for(int i=1;i<=9;i++)

                     {

                            for(int j=1;j<=9;j++)

                                   cout<<a[i][j];  //输出数独

                            cout<<endl;

                     }

              }

       }

       return 0;

}

编辑器加载中...

你可能感兴趣的:(sudo)