Sudoku(数独)

题目描述:都玩过这个游戏,同行同列不能出现相同的数字,同一个9格子中也不能相同的出现。

解决:dfs+回溯

把每行每列不能用的元素检出来,在搜索的时候看每9个格子的情况,用check函数, 用两个vis数组存放行的信息和列的信息

 

#include <iostream>
#include <cstdio>
using namespace std;
int map[10][10];
bool vis1[10][10],vis2[10][10];
bool found;
bool check(int x,int y,int val)
{//检测每9个格子中的数是否重复
    for(int i=(x-1)/3*3+1;i<=(x-1)/3*3+3;i++)
      for(int j=(y-1)/3*3+1;j<=(y-1)/3*3+3;j++)
           if(map[i][j]==val)return false;
        return true;
}
void show()
{
    for(int i=1;i<=9;i++) 
        {
          for(int j=1;j<=9;j++)printf("%d",map[i][j]);  
          printf("\n");
        }
}
void dfs(int x,int y)
{
    if(found)return;
   //返回条件是x=9并且y=10
    if(x==9 && y==10){found=true; show();return; }
   //若y=10,进行下一行
    if(y==10)dfs(x+1,1);
    //下标为x,y的元素是否已经有了数字,有数字的话进行下一个,
    //没有的话填写数,并回溯
    if(map[x][y])dfs(x,y+1);
    else  
    {
        for(int i=1;i<=9;i++)
        {
            if(!vis1[x][i] && !vis2[y][i] && check(x,y,i) )
            {
                if(y<=9)
                {
                    vis1[x][i]=1;
                    vis2[y][i]=1;
                    map[x][y]=i;
                    dfs(x,y+1);
                    vis1[x][i]=0;
                    vis2[y][i]=0;
                    map[x][y]=0;
                }
            }
        }   
    }
}
int main()
{
    int icase;
    scanf("%d",&icase);
    while(icase--)
    {
        char c;
        found=false;
        memset(vis1,0,sizeof(vis1));
        memset(vis2,0,sizeof(vis2));
         //预处理
        for(int i=1;i<=9;i++)
        {
            getchar();
            for(int j=1;j<=9;j++)
            {
                scanf("%c",&c);
                map[i][j]=c-'0'; 
                if(map[i][j])
                {//vis1数组存放的是行中是否使用,vis2存放列中某个数是否使用
                    vis1[i][map[i][j]]=1;
                    vis2[j][map[i][j]]=1;
                }
            }
        }
       //下标从1开始
        dfs(1,1);
    }
    system("pause");
    return 0;
}

原文地址:https://www.cnblogs.com/hpustudent/p/2174245.html