C语言--解数独程序源码

用C语言写的解数独的程序。在linux下测试成功运行。

效果如图:

这是带解的数独,需要填写的部分用数字0代替。

这是程序运行后的效果图。看看,数独已经搞定啦~~~

 

程序源码如下:

 

 

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #define SIZE 9  
  5. #define get_low_bit(x) ((~x&(x-1))+1)  
  6.   
  7. struct{  
  8.     int left;  
  9.     char num;     
  10.     char try;  
  11. }board[SIZE][SIZE];  
  12.   
  13. int bit2num(int bit)  
  14. {  
  15.     switch(bit){  
  16.         case 1:case 2:  
  17.             return bit;   
  18.         case 4:  
  19.             return 3;  
  20.         case 8:  
  21.             return 4;  
  22.         case 16:  
  23.             return 5;  
  24.         case 32:  
  25.             return 6;     
  26.         case 64:          
  27.             return 7;     
  28.         case 128:  
  29.             return 8;     
  30.         case 256:  
  31.             return 9;  
  32.     }     
  33. }  
  34.   
  35. void printf_res()  
  36. {  
  37.     int i, j, k;      
  38.       
  39.     for(i=0; i<SIZE; i++)  
  40.     {  
  41.         if(i%3==0)    
  42.         {  
  43.             for(j=0; j<SIZE*2+4; j++)  
  44.                 putchar('-');  
  45.             putchar('\n');  
  46.         }         
  47.           
  48.         for(j=0; j<SIZE; j++)  
  49.         {  
  50.             if(j%3==0)  
  51.                 putchar('|');  
  52.             if(board[i][j].num > 0)  
  53.                 printf("\033[0;31m%2d\033[0m", board[i][j].num);  
  54.             else  
  55.                 printf("%2d", board[i][j].try);  
  56.         }     
  57.         printf("|\n");  
  58.     }  
  59.     for(i=0; i<SIZE*2+4; i++)  
  60.         putchar('-');  
  61.     putchar('\n');  
  62. }  
  63.   
  64. void sub(int i, int j, int bit)  
  65. {  
  66.     int k, m;     
  67.       
  68.     for(k=0; k<SIZE; k++)  
  69.     {  
  70.         board[k][j].left &= ~bit;  
  71.         board[i][k].left &= ~bit;  
  72.     }         
  73.       
  74.     for(k=i/3*3; k<(i/3+1)*3; k++)  
  75.         for(m=j/3*3; m<(j/3+1)*3; m++)  
  76.             board[k][m].left &= ~bit;     
  77. }  
  78.   
  79. void init()  
  80. {  
  81.     int i, j;     
  82.           
  83.     for(i=0; i<SIZE; i++)  
  84.         for(j=0; j<SIZE; j++)  
  85.             if(board[i][j].num > 0)  
  86.                 sub(i, j, 1<<(board[i][j].num-1));  
  87.             else if(board[i][j].try > 0)  
  88.                 sub(i, j, 1<<(board[i][j].try-1));  
  89. }  
  90.   
  91. void add(int i, int j, int bit)  
  92. {  
  93.     int k, m;  
  94.   
  95.     for(k=0; k<SIZE; k++)  
  96.     {  
  97.         board[k][j].left |= bit;  
  98.         board[i][k].left |= bit;  
  99.     }  
  100.     for(k=i/3*3; k<(i/3+1)*3; k++)  
  101.         for(m=j/3*3; m<(j/3+1)*3; m++)  
  102.             board[k][m].left |= bit;  
  103. }  
  104.   
  105. void solve(int pos)  
  106. {  
  107.     int i=pos/SIZE;   
  108.     int j=pos%SIZE;   
  109.     int bit, left;  
  110.   
  111.     if(pos == SIZE*SIZE)  
  112.     {  
  113.         printf_res();  
  114.         exit(0);          
  115.     }  
  116.     if(board[i][j].num > 0)  
  117.         solve(pos+1);     
  118.     else  
  119.         for(left=board[i][j].left; left; left&=(left-1))  
  120.         {  
  121.             bit = get_low_bit(left);  
  122.             sub(i, j, bit);  
  123.             board[i][j].try = bit2num(bit);  
  124.   
  125.             solve(pos+1);  
  126.               
  127.             add(i, j, bit);  
  128.             board[i][j].try=0;  
  129.             init();       
  130.         }         
  131. }  
  132.   
  133. int main()  
  134. {  
  135.     int i, j, c;  
  136.   
  137.     for(i=0; i<SIZE; i++)  
  138.         for(j=0; j<SIZE; j++)  
  139.         {  
  140.             while((c=getchar())<'0' || c>'9')  
  141.                 ;  
  142.             board[i][j].num = c-'0';  
  143.             board[i][j].try = 0;  
  144.             board[i][j].left = 0x0001FF;          
  145.         }                 
  146.     init();  
  147.     solve(0);  
  148.   
  149.     return 0;  
  150. }  

转载于:https://my.oschina.net/zyyhhh/blog/752623

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值