poj 3074 Sudoku(Dancing Links)

來源:互聯網
上載者:User

標籤:acm   c   演算法   

Sudoku
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 8152   Accepted: 2862

Description

In the game of Sudoku, you are given a large 9 × 9 grid divided into smaller 3 × 3 subgrids. For example,

. 2 7 3 8 . . 1 .
. 1 . . . 6 7 3 5
. . . . . . . 2 9
3 . 5 6 9 2 . 8 .
. . . . . . . . .
. 6 . 1 7 4 5 . 3
6 4 . . . . . . .
9 5 1 8 . . . 7 .
. 8 . . 6 5 3 4 .

Given some of the numbers in the grid, your goal is to determine the remaining numbers such that the numbers 1 through 9 appear exactly once in (1) each of nine 3 × 3 subgrids, (2) each of the nine rows, and (3) each of the nine columns.

Input

The input test file will contain multiple cases. Each test case consists of a single line containing 81 characters, which represent the 81 squares of the Sudoku grid, given one row at a time. Each character is either a digit (from 1 to 9) or a period (used to indicate an unfilled square). You may assume that each puzzle in the input will have exactly one solution. The end-of-file is denoted by a single line containing the word “end”.

Output

For each test case, print a line representing the completed Sudoku puzzle.

Sample Input

.2738..1..1...6735.......293.5692.8...........6.1745.364.......9518...7..8..6534.......52..8.4......3...9...5.1...6..2..7........3.....6...1..........7.4.......3.end

Sample Output

527389416819426735436751829375692184194538267268174593643217958951843672782965341416837529982465371735129468571298643293746185864351297647913852359682714128574936

Source

Stanford Local 2006

題意:

就是經典的數獨問題。

思路:

搜尋。但是得藉助Dancing Links加速。關鍵就在於怎樣把數獨問題抽象成一個精確覆蓋問題了。

我們首先考慮數獨的遊戲規則。

1.每個格子都必須填一個數字。

2.每一行1-9這幾個數字都必須出現一次。

3.每一列1-9這幾個數字都必須出現一次。

4.每一宮格1-9這幾個數字都必須出現一次。

我們知道Dancing Links的精確覆蓋智能處理0,1的序列覆蓋每一列為一個約束條件。那麼我們就必須把上述約束轉換成0,1矩陣。

對於1。我們用第(i-1)*9+j列為1表示i行j列的已經填數。一共佔用81列。

對於2.我們用81+(i-1)*9+v列表示第i行已經有v這個值。一共佔用81列。

對於3.我們用162+(j-1)*9+v列表示第j列已經有v這個值。一共佔用81列。

對於3.我們用243+(3*((i-1)/3)+(j+2)/3-1)+v列表示第3*((i-1)/3)+(j+2)/3宮格已經有v這個值。一共佔用81列。

ps:i,j都從1開始。3*((i-1)/3)+(j+2)/3為通過i,j確定的宮格數。

這樣就會為每個宮格確定一個01序列約束。

然後建好矩陣後。套上精確覆蓋模板後就ok了。

詳細見代碼:

#include<iostream>#include<stdio.h>#include<string.h>using namespace std;const int INF=0x3f3f3f3f;const int maxn=3645;//每個格子可能有9個取值。所以最多有81*9行。然後243列。int U[maxn],D[maxn],L[maxn],R[maxn],C[maxn],row[maxn];//上下左右指標。c[i]結點i對應的列。row[i]結點i對應的行號。int S[350],H[800],ans[100];//S[i]為i列1的個數。H[i]為i行的尾指標。int n,m,cnt,deep;struct node{    int x,y,v;} st[maxn];char maze[150],path[150];void init(){    int i;    for(i=1;i<=800;i++)        H[i]=-1;    for(i=0;i<=324;i++)    {         S[i]=0;         L[i+1]=i;         R[i]=i+1;         U[i]=D[i]=i;    }    R[324]=deep=0;    cnt=325;}void Insert(int r,int c){                        //頭插法建鏈表    U[cnt]=c,D[cnt]=D[c];//確定新增結點上下指標資訊    U[D[c]]=cnt,D[c]=cnt;//恢複鏈表資訊    if(H[r]==-1)         //確定左右指標資訊        H[r]=L[cnt]=R[cnt]=cnt;//加入頭    else    {        L[cnt]=H[r],R[cnt]=R[H[r]];//頭插法        L[R[H[r]]]=cnt,R[H[r]]=cnt;    }    S[c]++;//更新附加資訊    row[cnt]=r;    C[cnt++]=c;}void Remove(int c)//移除c列。{    int i,j;    R[L[c]]=R[c],L[R[c]]=L[c];    for(i=D[c];i!=c;i=D[i])        for(j=R[i];j!=i;j=R[j])            D[U[j]]=D[j],U[D[j]]=U[j],S[C[j]]--;}void Resume(int c)//還原c列。{    int i,j;    R[L[c]]=L[R[c]]=c;    for(i=D[c];i!=c;i=D[i])        for(j=R[i];j!=i;j=R[j])            D[U[j]]=U[D[j]]=j,S[C[j]]++;}bool dfs(){    if(R[0]==0)        return true;    int i,j,c,miv=INF;    for(i=R[0];i;i=R[i])        if(S[i]<miv)            miv=S[i],c=i;    Remove(c);//處理第c列    for(i=D[c];i!=c;i=D[i])    {        for(j=R[i];j!=i;j=R[j])            Remove(C[j]);        ans[deep++]=row[i];        if(dfs())            return true;        for(j=L[i];j!=i;j=L[j])            Resume(C[j]);        deep--;    }    Resume(c);    return false;}int main(){    int i,j,v,r,p;    while(gets(maze))    {        if(maze[0]=='e')            break;        init();        r=1;        for(i=1;i<=9;i++)//每行為一個格子的一種選擇。        {            for(j=1;j<=9;j++)            {                if(maze[(i-1)*9+j-1]=='.')                {                    for(v=1;v<=9;v++)                    {                        Insert(r,(i-1)*9+j);                        Insert(r,81+(i-1)*9+v);                        Insert(r,162+(j-1)*9+v);                        Insert(r,243+(((i-1)/3)*3+(j+2)/3-1)*9+v);                        st[r].x=i,st[r].y=j,st[r].v=v;                        r++;                    }                }                else                {                    v=maze[(i-1)*9+j-1]-'0';                    Insert(r,(i-1)*9+j);                    Insert(r,81+(i-1)*9+v);                    Insert(r,162+(j-1)*9+v);                    Insert(r,243+(((i-1)/3)*3+(j+2)/3-1)*9+v);                    st[r].x=i,st[r].y=j,st[r].v=v;                    r++;                }            }        }        dfs();        for(i=0;i<deep;i++)        {            p=ans[i];            path[(st[p].x-1)*9+st[p].y-1]='0'+st[p].v;        }        path[deep]=0;        printf("%s\n",path);    }    return 0;}

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.