[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;
        }
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章