c语言数独出题程序,C语言实现的数独解题程序

用最暴力的递归方式在所有可能的空间中寻找数独的解法。试了一下,不管多难的数独都能在1s内找到所有答案,所以也没有采取更智能的算法进行优化,如加入人的逻辑推理算法。

这里只是把一种最笨的方法分享出来,只是感叹现在的计算机运算能力太强大了。源码如下:

#include #include /*数独二维数组*/ int g_s[9][9] = {     {0,4,0,7,0,0,0,0,0}, {9,2,0,0,0,0,6,0,7}, {8,3,0,0,0,5,4,0,0}, {0,1,0,0,0,3,0,0,0}, {0,0,0,2,0,1,0,0,0}, {0,0,0,5,0,0,0,4,0}, {0,0,4,9,0,0,0,7,1}, {3,0,5,0,0,0,0,9,4}, {0,0,0,0,0,8,0,6,0} }; /*打印当前数独状态*/ int prt() {     int i = 0;     int j = 0;     for(i = 0;i < 9;i++)     {         for(j = 0;j < 9;j++)         {             printf("%d ",g_s[i][j]);         }         printf("\n");     }     getchar(); } /*获取一个位置当前所有可能的解*/ int get_all_num(int i,int j,int a[9]) {     int s[9] = {1,2,3,4,5,6,7,8,9};     int row,col,k;     /*删除当前行中已出现的值*/     for(col = 0;col < 9;col++)     {         k = g_s[i][col];         if(k != 0)         {             s[k-1] = 0;         }     }     /*删除当前列中已出现的值*/     for(row = 0;row < 9;row++)     {         k = g_s[row][j];         if(k != 0)         {             s[k-1] = 0;         }     }     /*删除当前九宫格中已出现的值*/     row = (i/3)*3;     col = (j/3)*3;     for(i = row;i < (row+3);i++)     {         for(j = col;j < (col+3);j++)         {             k = g_s[i][j];             if(k != 0)             {                 s[k-1] = 0;             }         }     }     i = 0;     for(k = 0;k < 9;k++)     {         if(s[k] != 0)         {             a[i] = s[k];             i++;         }     }          return i; } /*判断当前行是否合法*/ int check_row(int i,int num) {     int j = 0;     for(j = 0;j < 9;j++)     {         if(g_s[i][j] == num)         {             return 0;         }     }          return 1; } /*判断当前列是否合法*/ int check_col(int j,int num) {     int i = 0;     for(i = 0;i < 9;i++)     {         if(g_s[i][j] == num)         {             return 0;         }     }     return 1;          } /*判断当前九宫格是否合法*/ int check_block(int i,int j,int num) {     int row = (i/3)*3;     int col = (j/3)*3;     int k = 0;     int l = 0;          for(k = row;k < (row+3);k++)     {         for(l = col;l < (col+3);l++)         {             if(g_s[k][l] == num)             {                 return 0;             }         }     }          return 1; } /*尝试一个解*/ int try_one(int i,int j,int num) {     if(check_row(i,num) && check_col(j,num) &&         check_block(i,j,num))     {         g_s[i][j] = num;         //prt();         return 1;     }     return 0; } /*获取下一个要填空的位置*/ int get_next(int *pi,int *pj) {     int i = *pi;     int j = *pj;     int r = i;     int c = 0;     j++;     for(;r < 9;r++)     {         for(c = j;c < 9;c++)         {             if(g_s[r][c] == 0)             {                 *pi = r;                 *pj = c;                 return;             }         }         j = 0;     }     if(r == 9)     {         return 0;     }     *pi = r;     *pj = c;     return 1; } /*找到一个解*/ void finish() {     printf("\n find a solution: \n");     prt(); } /*处理一个位置*/ int do_one(int i,int j) {     int row = i;     int col = j;     int n = 0;     int k = 0;     int a[9] = {0};          /*当前位置有解,下一个位置*/     if(g_s[row][col] != 0)     {         /*获取下一个无解的位置*/         if(get_next(&row,&col))         {             /*对一下个位置递归操作*/             do_one(row,col);         }         /*都有解了,成功*/         else         {             finish();         }         /*当前位置有解,直接回溯*/         return;     }     /*当前位置无解*/     else     {         /*获取当前位置的所有可能解*/         n = get_all_num(i,j,a);                  for(k = 0;k < n;k++)         {             /*尝试所有可能的解,这里是重复操作,就不改了*/             if(try_one(i,j,a[k]))             {                 row = i;                 col = j;                 /*此位置找到合适的了,下一个*/                 if(get_next(&row,&col))                 {                         do_one(row,col);                 }                 /*当前位置已有解且没有下一个了,结束*/                 else                 {                     finish();                 }             }         }         /*要向前回溯,则这个位置找到的解无效,回溯前清0*/         g_s[i][j] = 0;         //prt();         return;     }      } int main() {     do_one(0,0);     return 0; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值