給定乙個不完整9*9數獨,
未填部分用0表示,
恢復數獨,並列印
在讀入的時候,
我們開幾個陣列,
sudoku[9][9],相當於這張數獨地圖,上面記錄值
checkrow[9][10],第i行,是否出現過數v,1<=v<=9
checkcol[9][10],第j列,是否出現過數v,1<=v<=9
square[9][10],第k塊,是否出現過數v,1<=v<=9
塊的定義,
即中漢字數字順序,對應0-8塊,
k=i/3*3+j/3可表示。
//**於網路
我們從(0,0)開始dfs,
如果行末,就dfs下一行行首;
如果非行末,就dfs本行下一列,
如果到(9,0)了,說明前面均無衝突。
然後就是dfs經典三段論。
①試數,對應修改
②向更深層次搜尋
③(如果能到這裡,說明②失敗)將①還原
博主這篇文章真的是好評,
**風格也很好,剪枝也減的恰到好處,
搜到乙個可行解,isdone就返回,
雖然沒加一句注釋,但通俗易懂。
qaq數獨的確是一種經典題,還是要多練為妙
全oj大概有那麼五六個數獨題吧,
16*16的,靶型數獨的,以後再補吧
講道理,貼**裡面的i,個人覺得,好吃藕
#include #include #include #include #include #include #include #include #include #include #include const double inf=0x3f3f3f3f;
const int maxn=1e5+10;
const int mod=1e9+7;
const int mod=998244353;
const double eps=1e-7;
typedef long long ll;
#define vi vector#define si set#define pii pair#define pi acos(-1.0)
#define pb push_back
#define mp make_pair
#define lowbit(x) (x&(-x))
#define sci(x) scanf("%d",&(x))
#define scll(x) scanf("%lld",&(x))
#define sclf(x) scanf("%lf",&(x))
#define pri(x) printf("%d",(x))
#define rep(i,j,k) for(int i=j;i<=k;++i)
#define per(i,j,k) for(int i=j;i>=k;--i)
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
char tmp[9];
int sudoku[9][9];
bool square[9][10];//第i個3*3塊,數j是否已經出現
bool checkrow[9][10];//第i行,數j是否已經出現
bool checkcol[9][10];//第i列,數j是否已經出現
bool isdone;//是否搜到乙個可行解
void init()
void dfs(int i,int j)//當前判sodaku[i][j]是否合法
puts("");
} return;
} if(isdone)return;//已經搜到乙個可行解了,把剩下的剪枝
if(sudoku[i][j])//這裡已經置入乙個數了
else
}} }
int main()
}} dfs(0,0);
} return 0;
}
POJ 2676 Sudoku 數獨 解題報告
搜尋依舊寫的稀爛。大概就是數獨吧。橫 數 小九宮格內不重複。這種題主要的手法還是搜尋 暴力列舉。這道題主要的難點是以什麼為單位開始搜 其實也不難 以及怎麼設定vis剪枝。在這裡,我選擇了以搜尋二叉樹構建的map來記錄vis 畢竟map查詢起來較容易 將9個小九宮格 每行 每列各構建乙個map來記錄,...
POJ2676 Sudoku 詳解優化
思路是很簡單的,類似於八皇后問題 暴力搜 用h i j 標記第i行中是否存在j 同理,l i j 標識第i列中是否存在j k i j 第i個方塊中是否存在j 難的是如何進行剪枝,可行的乙個方法是記錄每個初始為0的點的座標與可能放置的數字的個數,從少往多遍歷,這樣能有效的減小搜尋樹的規模。剪枝優化待更...
poj 2676 數獨問題 dfs
題意 完成數獨程式,數獨要求每行每列且每個3 3矩陣都必須是1 9的數字組成。思路 dfs 用row i n 記錄第i行n存在 用col j n 記錄第j列n存在 grid k n 記錄第k個3 3中的n存在 遍歷的時候,先把列遍歷完然後在遍歷行 if map r c 現在推第乙個矩陣為 0,0 0...