zoukankan      html  css  js  c++  java
  • POJ2676Sudoku

    转载请注明出处:優YoU  http://user.qzone.qq.com/289065406/blog/1303713313

     

    大致题意:

    九宫格问题,也有人叫数独问题

    把一个99列的网格,再细分为93*3的子网格,要求每行、每列、每个子网格内都只能使用一次1~9中的一个数字,即每行、每列、每个子网格内都不允许出现相同的数字。

     

    0是待填位置,其他均为已填入的数字。

    要求填完九宫格并输出(如果有多种结果,则只需输出其中一种)

    如果给定的九宫格无法按要求填出来,则输出原来所输入的未填的九宫格

     

    解题思路:

    DFS试探,失败则回溯

     

    用三个数组进行标记每行、每列、每个子网格已用的数字,用于剪枝

    bool row[10][10];    //row[i][x]  标记在第i行中数字x是否出现了

    bool col[10][10];    //col[j][y]  标记在第j列中数字y是否出现了

    bool grid[10][10];   //grid[k][x] 标记在第k3*3子格中数字z是否出现了

     

    row col的标记比较好处理,关键是找出grid子网格的序号与 ij的关系

    即要知道第ij列的数字是属于哪个子网格的

     

    首先我们假设子网格的序号如下编排:


    由于1<=ij<=9我们有: (其中“/”是C++中对整数的除法)


    a= i/3 , b= j/3  ,根据九宫格的 行列 子网格 关系,我们有:


     

    不难发现 3a+b=k

    3*(i/3)+j/3=k

     

    又我在程序中使用的数组下标为 1~9grid编号也为1~9

    因此上面的关系式可变形为 3*((i-1)/3)+(j-1)/3+1=k

     

     

    有了这个推导的关系式,问题的处理就变得非常简单了,直接DFS即可

     

     

      1 //Memory Time 
    2 //184K 422MS
    3
    4 #include<iostream>
    5 using namespace std;
    6
    7 int map[10][10]; //九宫格
    8
    9 bool row[10][10]; //row[i][x] 标记在第i行中数字x是否出现了
    10 bool col[10][10]; //col[j][y] 标记在第j列中数字y是否出现了
    11 bool grid[10][10]; //grid[k][x] 标记在第k个3*3子格中数字z是否出现了
    12
    13 //(这里说明的字母不代表下面程序中的变量)
    14
    15 bool DFS(int x,int y)
    16 {
    17 if(x==10)
    18 return true;
    19
    20 bool flag=false;
    21
    22 if(map[x][y])
    23 {
    24 if(y==9)
    25 flag=DFS(x+1,1);
    26 else
    27 flag=DFS(x,y+1);
    28
    29 if(flag) //回溯
    30 return true;
    31 else
    32 return false;
    33 }
    34 else
    35 {
    36
    37 int k=3*((x-1)/3)+(y-1)/3+1;
    38
    39 for(int i=1;i<=9;i++) //枚举数字1~9填空
    40 if(!row[x][i] && !col[y][i] && !grid[k][i])
    41 {
    42 map[x][y]=i;
    43
    44 row[x][i]=true;
    45 col[y][i]=true;
    46 grid[k][i]=true;
    47
    48 if(y==9)
    49 flag=DFS(x+1,1);
    50 else
    51 flag=DFS(x,y+1);
    52
    53 if(!flag) //回溯,继续枚举
    54 {
    55 map[x][y]=0;
    56
    57 row[x][i]=false;
    58 col[y][i]=false;
    59 grid[k][i]=false;
    60 }
    61 else
    62 return true;
    63 }
    64 }
    65 return false;
    66 }
    67
    68 int main(int i,int j)
    69 {
    70 int test;
    71 cin>>test;
    72 while(test--)
    73 {
    74 /*Initial*/
    75
    76 memset(row,false,sizeof(row));
    77 memset(col,false,sizeof(col));
    78 memset(grid,false,sizeof(grid));
    79
    80 /*Input*/
    81
    82 char MAP[10][10];
    83 for(i=1;i<=9;i++)
    84 for(j=1;j<=9;j++)
    85 {
    86 cin>>MAP[i][j];
    87 map[i][j]=MAP[i][j]-'0';
    88
    89 if(map[i][j])
    90 {
    91 int k=3*((i-1)/3)+(j-1)/3+1;
    92 row[i][ map[i][j] ]=true;
    93 col[j][ map[i][j] ]=true;
    94 grid[k][ map[i][j] ]=true;
    95 }
    96 }
    97
    98 /*Fill the Sudoku*/
    99
    100 DFS(1,1);
    101
    102 for(i=1;i<=9;i++)
    103 {
    104 for(j=1;j<=9;j++)
    105 cout<<map[i][j];
    106 cout<<endl;
    107 }
    108 }
    109 return 0;
    110 }
  • 相关阅读:
    新手安装Oracle数据库指南
    新手IntelliJ IDEA入门指南
    IntelliJ IDEA 开发工具快捷键大全
    打印杨辉三角
    个人作业-Alpha项目测试
    第三次作业
    第二次作业
    第一次作业-林楠-201731062428
    手把手教你实现在Monaco Editor中使用VSCode主题
    一文搞懂jsBridge的运行机制
  • 原文地址:https://www.cnblogs.com/lyy289065406/p/2122549.html
Copyright © 2011-2022 走看看