洛谷-數獨-搜索與回溯

題目描述

數獨是根據9×9盤面上的已知數字,推理出全部剩餘空格的數字,並知足每一行、每一列、每個粗線宮內的數字均含1-9,不重複。每一道合格的數獨謎題都有且僅有惟一答案,推理方法也以此爲基礎,任何無解或多解的題目都是不合格的。數組

芬蘭一位數學家號稱設計出全球最難的「數獨遊戲」,並刊登在報紙上,讓你們去挑戰。函數

這位數學家說,他相信只有「智慧最頂尖」的人才有可能破解這個「數獨之謎」。spa

據介紹,目前數獨遊戲的難度的等級有一道五級,一是入門等級,五則比較難。不過這位數學家說,他所設計的數獨遊戲難度等級是十一,能夠說是因此數獨遊戲中,難度最高的等級他還表示,他目前還沒遇到解不出來的數獨遊戲,所以他認爲「最具挑戰性」的數獨遊戲並無出現。設計

輸入輸出格式

輸入格式:code

一個未填的數獨blog

輸出格式:遊戲

填好的數獨數學

輸入輸出樣例

輸入樣例#1:
8 0 0 0 0 0 0 0 0 
0 0 3 6 0 0 0 0 0 
0 7 0 0 9 0 2 0 0 
0 5 0 0 0 7 0 0 0 
0 0 0 0 4 5 7 0 0 
0 0 0 1 0 0 0 3 0 
0 0 1 0 0 0 0 6 8 
0 0 8 5 0 0 0 1 0 
0 9 0 0 0 0 4 0 0
輸出樣例#1:
8 1 2 7 5 3 6 4 9 
9 4 3 6 8 2 1 7 5 
6 7 5 4 9 1 2 8 3 
1 5 4 2 3 7 8 9 6 
3 6 9 8 4 5 7 2 1 
2 8 7 1 6 9 5 3 4 
5 2 1 9 7 4 3 6 8 
4 3 8 5 2 6 9 1 7 
7 9 6 3 1 8 4 5 2

說明

你猜,你猜,你猜猜猜it

猜不出來吧,我不告訴你~~~io

思路:這題就是簡單的搜索題目,首先咱們要明確搜索什麼:首先咱們能夠把從1到9中的每個數字放進去試試看,若是這個數字在當前九宮格內未出現過而且在當前行當前列未出現,就能夠放進去,若是出現過了,就回溯一下嗯。

  咱們對於「這個數字有沒有在當前行當前列中出現過」這個判斷,我是用並查集的方法來作的,好比第一行有一個數字8,在當前行內出現了,咱們就把x[1][8]標記爲1,這樣咱們下次判斷8是否在這行中出現時,只需判斷x[1][8]是否爲1就好了,同理對於列也是同樣。

  在這裏能夠用flag記錄當前放置數字的步數,每次放一個就flag++,這樣當flag=9*9=81時,說明已經放滿了,輸出便可。

代碼以下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <stdlib.h>
 4 /*==============================*///一些全局變量 
 5 int flag=0;
 6 int num[9][9]={0};//原始數據數組 
 7 int x[9][9]={0};//標記這一行是否有重複的 
 8 int y[9][9]={0};//標記這一列是否有重複的 
 9 /*==============================*/
10 int inspect(int i,int j,int dj)//檢查當前這個數字是否在九宮格中有重複,傳入的是當前數字的座標i,j,和這個數dj也就是傳過來的i值 
11 {
12     i=i/3*3;
13     j=j/3*3;
14     for(int ii=0;ii<3;ii++)
15     {
16         for(int jj=0;jj<3;jj++)
17         {
18             if(num[i+ii][j+jj]==dj)//在這個九宮格出現過,返回非 
19             {
20                 return 0;
21             }
22         }
23     }
24     return 1;//不然是真 
25 }
26 void shuchu()//輸出這個數組 
27 {
28     for(int i=0;i<9;i++)
29     {
30         for(int j=0;j<9;j++)
31         {
32             printf("%d ",num[i][j]);
33         }
34         printf("\n");
35     }
36 } 
37 
38 void DFS(int flag)
39 {
40     if(flag==9*9)//若是全部空都被填滿,傳入輸出結果函數,輸出結果
41     {
42         shuchu(); 
43         exit(0);//毀滅程序
44     }
45     else
46     {
47         if(num[flag/9][flag%9]!=0)//若是這個位置已經填好數字了,直接跳過便可
48         {
49             DFS(flag+1);//搜索下一個 
50         }
51         else//若是是空位,放數字 
52          {
53               for(int i=1;i<=9;i++)
54                  {
55                  if((x[flag/9][i-1]==0)&&(y[flag%9][i-1]==0)&&(inspect(flag/9,flag%9,i)))//這個數字在當前行和列沒有重複而且在九宮格中也沒有重複哦~ 我就放上去好了 
56                  {
57                     num[flag/9][flag%9]=i;//把當前i放入數組 
58                     x[flag/9][i-1]=1;//在當前行已經使用過了 
59                     y[flag%9][i-1]=1;//在當前列已經使用過了 
60                     DFS(flag+1);//搜索下一個 
61                     /*===========================*///還原現場,回溯 
62                     num[flag/9][flag%9]=0;
63                     x[flag/9][i-1]=0;
64                     y[flag%9][i-1]=0;
65                     /*===========================*/
66                 }
67             }        
68         }
69     } 
70     
71 }
72 int main()
73 {
74     int i,j;
75     for(i=0;i<9;i++)
76     {
77         for(j=0;j<9;j++)
78         {
79             scanf("%d",&num[i][j]);            
80             /*==================================*/
81             if(num[i][j])
82             {
83                 x[i][num[i][j]-1]=1;//標記這個數字在當前行已經被使用過 
84                 y[j][num[i][j]-1]=1;//標記這個數字在當前行已經被使用過 
85             }          
86             /*==================================*/        
87         }
88     }
89     DFS(0);//調用深度優先搜索 
90     return 0;
91 }
相關文章
相關標籤/搜索