[DFS]poj2676(2918)

题意:
数独问题,给出一些点,然后要求填满格子。每行没列1-9不能重复,每个3*3的小格子也不能重复。

分析:
暴力搜索,那么主要的问题就是每次如何判断是否冲突。行和列的比较好想,row[i][j]=1表示第i行的j已经被占了,col[i][j]=1表示第i列的j已经被占了,那么每个小格子呢?
首先,每行每列都是012、345、678那么每个j/3表示它在这以行的第j/3个格子里,i/3表示在第i/3行的格子,那么i/3*3+j/3就表示该点处于那个小格子里,同理g[i][j]表示第i个格子里的j已经被占了。
ok,剩下的就是代码递归实现了。

另外poj2918和本题是一样的,只不过输入输出格式不一样。亲测代码改过能AC。另外,poj的数独问题还有poj3074,poj3076 ,难度分别是poj2076=poj2918

#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
#define read freopen("q.in","r",stdin)
#define LL long long
#define maxn 1000
using namespace std;
char mp[10][10];
int grid[10][10];
bool row[10][10],col[10][10];
bool g[10][10];

bool dfs(int d)
{
   // cout<<d<<endl;
   if(d==81)return true;
   int x=d/9+1,y=d%9+1;
   bool f=false;
   if(grid[x][y])
   return dfs(d+1);
   else
   {
       int t=((x-1)/3)*3+(y-1)/3+1;
        for(int i=1;i<=9;i++)
        {
             //cout<<"EEE"<<f<<endl;
            if( !col[y][i] && !row[x][i] && !g[t][i])
            {
                grid[x][y]=i;
                col[y][i]=true;row[x][i]=true;g[t][i]=true;
                f= dfs(d+1);

                if(f)return true;
                else{
                col[y][i]=false;row[x][i]=false;g[t][i]=false;grid[x][y]=0;
                }
            }
       }
   }
   return false;
}
int main()
{
  //  read;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        int i,j;
        memset(row,false,sizeof(row));
        memset(col,false,sizeof(col));
        memset(grid,0,sizeof(grid));
        memset(g,false,sizeof(g));

        for(i=1;i<=9;i++)
        {
            for(j=1;j<=9;j++)
            {
                cin>>mp[i][j];
                grid[i][j]=mp[i][j]-'0';
                if(grid[i][j])
                {
                    int tmp=grid[i][j];
                    row[i][tmp]=true;
                    col[j][tmp]=true;
                    int x=((i-1)/3)*3+(j-1)/3+1;
                    g[x][tmp]=true;
                }
            }

        }
       bool flag= dfs(0);
      // cout<<flag<<endl;
        for(i=1;i<=9;i++)
        {
            for(j=1;j<=9;j++)cout<<grid[i][j];
            cout<<endl;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章