zoukankan      html  css  js  c++  java
  • c语言解数独

    来自:http://my.oschina.net/lovewxm/blog/288043?p=1

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3  
      4 #define BOOL int
      5 #define FALSE 1
      6 #define TRUE 0
      7  
      8 typedef struct node
      9 {
     10     int col;
     11     int row;
     12     int value[10];
     13 } Node;
     14  
     15 int findvalue(int sudoku[9][9], Node * node);
     16 BOOL general_inspection(int sudoku[9][9]);
     17 int blank_num(int sudoku[9][9]);
     18 Node * mem_alloc(int num_of_empty);
     19 void trace(int sudoku[9][9], Node * node_stack, int num_of_empty);
     20 void print_sudoku(int sudoku[9][9]);
     21  
     22  
     23 int main(void)
     24 {
     25     int sudoku[9][9] = {{0,0,5,3,0,0,0,0,0},
     26                         {8,0,0,0,0,0,0,2,0},
     27                         {0,7,0,0,1,0,5,0,0},
     28                         {4,0,0,0,0,5,3,0,0},
     29                         {0,1,0,0,7,0,0,0,6},
     30                         {0,0,3,2,0,0,0,8,0},
     31                         {0,6,0,5,0,0,0,0,9},
     32                         {0,0,4,0,0,0,0,3,0},
     33                         {0,0,0,0,0,9,7,0,0}
     34                         };
     35  
     36     int num_of_empty;
     37     //为回溯栈分配空间
     38     Node * node_stack;
     39  
     40     if(general_inspection(sudoku))
     41     {
     42         printf("此数独存在错误!请检查
    ");
     43         print_sudoku(sudoku);
     44         return 0;
     45     }
     46     num_of_empty = blank_num(sudoku);
     47     node_stack = mem_alloc(num_of_empty);
     48     trace(sudoku, node_stack, num_of_empty);
     49     print_sudoku(sudoku);
     50  
     51     return 0;
     52 }
     53  
     54 BOOL general_inspection(int sudoku[9][9])
     55 {
     56     int temp[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
     57     int i, j, m, n;
     58     for(i=0; i<9; i++)
     59         for(j=0; j<9; j++)
     60             if(sudoku[i][j]!=0)
     61             {
     62                 //检查所在行
     63                 for(m=0; m<10; m++)
     64                     temp[m] = 0;
     65                 for(m=0; m<9; m++)
     66                     if(sudoku[i][m]!=0)
     67                     {
     68                         if(temp[sudoku[i][m]]==0)
     69                             temp[sudoku[i][m]] = 1;
     70                         else
     71                             return FALSE;
     72                     }
     73                 //检查所在列
     74                 for(m=0; m<10; m++)
     75                     temp[m] = 0;
     76                 for(m=0; m<9; m++)
     77                     if(sudoku[m][j]!=0)
     78                     {
     79                         if(temp[sudoku[m][j]]==0)
     80                             temp[sudoku[m][j]] = 1;
     81                         else
     82                             return FALSE;
     83                     }
     84                 //检查所在九宫格
     85                 for(m=0; m<10; m++)
     86                     temp[m] = 0;
     87                 for(m=0; m<3; m++)
     88                     for(n=0; n<3; n++)
     89                         if(sudoku[i/3*3+m][j/3*3+n]!=0)
     90                         {
     91                             if(temp[sudoku[i/3*3+m][j/3*3+n]]==0)
     92                                 temp[sudoku[i/3*3+m][j/3*3+n]] = 1;
     93                             else
     94                                 return FALSE;
     95                         }
     96             }
     97     return TRUE;
     98 }
     99  
    100 int blank_num(int sudoku[9][9])
    101 {
    102     //计算所给数独中待填入的空白数
    103     int i, j, num = 0;
    104     for(i=0; i<9; i++)
    105         for(j=0; j<9; j++)
    106             if(sudoku[i][j]==0)
    107                 num++;
    108     return num;
    109 }
    110  
    111 Node * mem_alloc(int num_of_empty)
    112 {
    113     Node * node_stack = (Node *)malloc(sizeof(struct node) * num_of_empty);
    114     if(node_stack==NULL)
    115     {
    116         printf("内存分配失败!
    ");
    117         exit(1);
    118     }
    119     return node_stack;
    120 }
    121  
    122  
    123 void trace(int sudoku[9][9], Node * node_stack, int num_of_empty)
    124 {
    125     int i, j, index, k = 0;
    126     //回溯法求解数独
    127     while(num_of_empty)
    128     {
    129         for(i=0; i<9; i++)
    130         {
    131             for(j=0; j<9; j++)
    132             {
    133                 if(sudoku[i][j]==0)
    134                 {
    135                     (node_stack + k)->col = i;
    136                     (node_stack + k)->row = j;
    137                     sudoku[i][j] = findvalue(sudoku, node_stack+k);
    138                     if(sudoku[i][j]==-1)
    139                     {
    140                         sudoku[i][j] = 0;
    141                         k--;
    142                         while((node_stack + k)->value[0]==0)
    143                         {
    144                             //当栈空,说明数独错误,无解
    145                             if(k==0)
    146                             {
    147                                 printf("此数独无解!
    ");
    148                                 //free(node_stack); //为啥这里一释放内存,就弹出debug assertion failed窗口啊!
    149                                 exit(1);
    150                             }
    151                             sudoku[(node_stack + k)->col][(node_stack + k)->row] = 0;
    152                             num_of_empty++;
    153                             k--;
    154                         }
    155                         for(index=1; index<10; index++)
    156                             if((node_stack + k)->value[index]==0)
    157                             {
    158                                 sudoku[(node_stack + k)->col][(node_stack + k)->row] = index;
    159                                 (node_stack + k)->value[index] = 1;
    160                                 (node_stack + k)->value[0]--;
    161                                 break;
    162                             }
    163                         num_of_empty++;
    164                         i = (node_stack + k)->col;
    165                         j = (node_stack + k)->row;
    166                     }
    167                     k++;
    168                     num_of_empty--;
    169                 }
    170             }
    171         }
    172     }
    173     //栈空间使用结束,释放
    174     free(node_stack);
    175     node_stack=NULL;
    176 }
    177  
    178 int findvalue(int sudoku[9][9], Node * node)
    179 {
    180     int m, n, i = node->col, j = node->row;
    181     //初始化栈中存储候选值的数组
    182     for(m=0; m<10; m++)
    183         node->value[m] = 0;
    184     for(m=1; m<10; m++)
    185     {
    186         node->value[sudoku[i][m-1]] = 1;
    187         node->value[sudoku[m-1][j]] = 1;
    188     }
    189     for(m=0; m<3; m++)
    190         for(n=0; n<3; n++)
    191             node->value[sudoku[i/3*3+m][j/3*3+n]] = 1;
    192  
    193     //node->value[0]记录候选值个数,前面的循环可能会修改掉它,需要重新赋0值
    194     node->value[0] = 0;
    195     for(m=1; m<10; m++)
    196         if(node->value[m]==0)    node->value[0]++;
    197     for(m=1; m<10; m++)
    198         if(node->value[m]==0)
    199         {
    200             node->value[m] = 1;
    201             node->value[0]--;
    202             break;
    203         }
    204  
    205     //返回候选值m,若无候选值可用,返回错误标记-1
    206     if(m==10)
    207         return -1;
    208     else
    209         return m;
    210 }
    211  
    212 void print_sudoku(int sudoku[9][9])
    213 {
    214     //打印数独
    215     int i, j;
    216     for(i=0; i<9; i++)
    217     {
    218         for(j=0; j<9; j++)
    219             printf("%2d ", sudoku[i][j]);
    220         printf("
    ");
    221     }
    222 }
  • 相关阅读:
    代码生成器所用到的东西
    被float.parse吃掉的0.03...
    Microsoft Visual Studio 2010 Ultimate ISO 官方下载地址
    关于.net实现网站模板机制(非标签替换)
    关于ACCESS的事务与存储过程的调用
    关于如何实现左中右三栏布局, 左右固定宽度,中间随屏幕自适应
    几个台湾优秀个人博客网站
    [转]MathType常见问题
    Qt中int转换成QString
    fatal error C1189: #error : The C++ Standard Library forbids macroizing keywords. Enable warning C4005 to find the forbidden macro.
  • 原文地址:https://www.cnblogs.com/boyiliushui/p/4501399.html
Copyright © 2011-2022 走看看