zoukankan      html  css  js  c++  java
  • 洛谷-数独-搜索与回溯

    题目描述

    数独是根据9×9盘面上的已知数字,推理出所有剩余空格的数字,并满足每一行、每一列、每一个粗线宫内的数字均含1-9,不重复。每一道合格的数独谜题都有且仅有唯一答案,推理方法也以此为基础,任何无解或多解的题目都是不合格的。

    芬兰一位数学家号称设计出全球最难的“数独游戏”,并刊登在报纸上,让大家去挑战。

    这位数学家说,他相信只有“智慧最顶尖”的人才有可能破解这个“数独之谜”。

    据介绍,目前数独游戏的难度的等级有一道五级,一是入门等级,五则比较难。不过这位数学家说,他所设计的数独游戏难度等级是十一,可以说是所以数独游戏中,难度最高的等级他还表示,他目前还没遇到解不出来的数独游戏,因此他认为“最具挑战性”的数独游戏并没有出现。

    输入输出格式

    输入格式:

    一个未填的数独

    输出格式:

    填好的数独

    输入输出样例

    输入样例#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

    说明

    你猜,你猜,你猜猜猜

    猜不出来吧,我不告诉你~~~

    思路:这题就是简单的搜索题目,首先我们要明确搜索什么:首先我们可以把从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("
    ");
    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 }
  • 相关阅读:
    Django 之Redis配置
    python之类中如何判断是函数还是方法
    Anaconda 虚拟环境安装及应用
    【转载】IDEA:XML配置提示URI is not registered
    idea中配置xml不自动提示解决方案
    Java接口成员变量和方法默认修饰符
    [转载]java中Date,SimpleDateFormat
    intellij idea 的全局搜索快捷键方法
    【转载】使用IntelliJ IDEA提示找不到struts-default文件
    【转载】Jmeter分布式部署测试-----远程连接多台电脑做压力性能测试
  • 原文地址:https://www.cnblogs.com/geek-007/p/6716467.html
Copyright © 2011-2022 走看看