数独的一个解法

     公司茶水间打扫卫生的人很喜欢研究数独问题,经常一个人拿着报纸解上面的数独问题,一次遇到了一个难度为四级的问题拿来问我,我研究了一会没做出来,真是没面子,因此想到写一个小程序来解决。程序只是简单的尝试每一个可能的数字。根据输入数据的情况,来排除一些无效的数字情况。
#include  < stdio.h >

#define  N   9
#define  VALID   (1)
#define  INVALID (-1)
struct  item  
{
    
int  x,y,value;
    
struct  item  *  next;
};

class  Item
{
public :
    Item()
    {
        
int  i ;
        
for (i  =   0  ; i  <  N ; i  ++  ) {
            data[i] 
=  VALID;
            m_nValid 
=  N ;
        }
        
        m_origit 
=   false ;
        m_nIndicator 
=   0 ;
        m_nCurValue 
=   0 ;
    }
    
void  SetNInvalid( int  n)  /*  index value  */
    {
        data[n] 
=  INVALID;
        m_nValid 
-- ;
    }
    
int  GetValid()
    {
        
return  m_nValid;
    }
    
void  SetOrigi( int  nvalue)  /*  value in the map, it should be the index +1  */
    {
        m_origit 
=   true  ;
        m_nCurValue 
=  nvalue;
        
for ( int  i  =   0  ; i  <  N ; i  ++ )
        {
            
if (i  +   1   !=  nvalue)
            {
                SetNInvalid(i);
            }
        }
    }
    
int  GetCurrentValue()
    {
        
return  m_nCurValue;
    }
    
void  SetCurrentValue( int  n)
    {
        m_nCurValue 
=  n;
    }
    
bool  IsOrigi()   /*  1 origit ; 0 not origit  */
    {
        
return  m_origit ;
    }
    
void  ResetIndicator()
    {
        m_nIndicator 
=   0 ;
        m_nCurValue 
=   0  ;
    }

    
int  GetNextPossibleValue()
    {
        
while (m_nIndicator  <  N  &&  data[m_nIndicator ]  ==  INVALID) {
            m_nIndicator
++ ;
        }
        m_nIndicator 
++  ;
        
if (m_nIndicator  >  N) {
            
return   - 1 ;
        }
        
return  (m_nIndicator );
    }
    
    
void  PrintPossibleValue()
    {
        
int  i ;
        
for (i  =   0  ; i  <  N ; i  ++ )
        {
            
if (data[i]  ==  VALID)
            {
                printf(
"  %d  " , i  +   1 );
            }
        }
    }

    
int   data[N] ;
    
bool  m_origit;
    
int  m_nValid;
    
int  m_nIndicator ;
    
int  m_nCurValue;
};

class  CGroupMap
{
public :
    CGroupMap()
    {
    }
    
    
void  InitMap( struct  item  *  first)
    {
        
while (first)
        {
            SetItem(first);
            first 
=  first -> next;
        }
    }
    
void  SetItem( struct  item  *  it)
    {
        
int  i ;
        m_map[it
-> x][it -> y].SetOrigi(it -> value);
        
        
for (i  =   0  ; i  <  N ; i  ++  )
        {
            
if ( i  !=  it -> y) {
                m_map[it
-> x][i].SetNInvalid(it -> value   -   1 );
            }
        }

        
for (i  =   0  ; i  <  N ; i  ++ )
        {
            
if ( i  !=  it -> x)
            {
                m_map[i][it
-> y].SetNInvalid(it -> value  -   1 );
            }
        }
    }
    
bool  Checkvalue( int  x,  int  y ,  int  value)
    {
        
int  i , j;
        
if (value  <   0   ||  value  >  N)  return   false ;
        
for ( i  =   0  ; i  <  N ; i  ++ )
        {
            
if (i  !=  y) {
                
if (m_map[x][i].GetCurrentValue()  ==  value)
                {
                    
return   false ;
                }
            }
        }

        
for ( i  =   0  ; i  <  N ; i  ++ )
        {
            
if ( i  !=  x)
            {
                
if (m_map[i][y].GetCurrentValue()  ==  value)
                {
                    
return   false ;
                }
            }
        }

        
int  fx , fy ,mx,my;
        
        fx 
=  x  / 3  ;
        fx 
=  fx  *   3 ;
        mx 
=  fx  +   3 ;

        fy 
=  y  /   3 ;
        fy 
=  fy  *   3 ;
        my 
=  fy  +   3 ;

        
for (i  =  fx ; i  <  mx ; i  ++ )
            
for ( j  =  fy ; j  <  my ; j  ++ )
            {
                
if (i  ==  x  &&  j  ==  y)  continue ;
                
if (m_map[i][j].GetCurrentValue()  ==  value)
                    
return   false ;
            }
        
return   true ;
    }

    
void  StartCal()
    {
        
int  x  =   0  , y  =   0  ;
        
int  value ;

        
while (x  <  N)
        {
            
while ( y  <  N)
            {
                
if (m_map[x][y].IsOrigi()  ==   true ) {
                    y 
++  ;
                    
continue ;
                }

                
do {
                    value 
=  m_map[x][y].GetNextPossibleValue() ;                    
                }
while (value  >   0   &&   Checkvalue(x,y,value)  ==   false );
                
                
                
if (value  >    0  )
                {
                        m_map[x][y].SetCurrentValue(value);
                        y 
++  ;
                }
                
else
                {
                    m_map[x][y].SetCurrentValue(
0 );
                    m_map[x][y].ResetIndicator();

                    
do
                    {
                        
if (y  ==   0  ) 
                        {
                            x 
--  ;
                            y 
=  N  -   1 ;
                        }
                        
else  
                        {
                            y 
-- ;
                        }
                    }
while (m_map[x][y].IsOrigi());
                }
                
            }
            x 
++ ;
            y 
=   0  ;
            
// Show();
        }
    }

    
void  Show()
    {
        
int  i , j ;
        printf(
" " );
        
for (i  =   0  ; i  <  N ; i  ++ )
            
for (j  =   0  ; j  <  N ; j  ++ )
            {
                
if (i  &&  j  %  N  ==   0 ) printf( " " );
                printf(
"  %d  " , m_map[i][j].GetCurrentValue());
            }
      printf(
" " );
    }

    
void  DumpPossible()
    {
        
int  i ,j ;
        
for (i  =   0  ; i  <  N ; i  ++ )
            
for (j  =   0  ; j  <  N ; j  ++ )
            {
                printf(
" (%d,%d) :  " ,i ,j );
                m_map[i][j].PrintPossibleValue();
                printf(
" " );
            }
    }
    Item   m_map[N][N] ;
};


struct  item  itArra[]  =
    {
        {
0 , 0 , 5 , NULL},
        {
0 , 3 , 1 , NULL},
        {
0 , 4 , 8 , NULL},
        {
0 , 5 , 2 , NULL},
        {
0 , 7 , 4 , NULL},
        {
1 , 3 , 6 , NULL},
        {
1 , 5 , 7 , NULL},
        {
1 , 7 , 2 , NULL},
        {
2 , 5 , 5 , NULL},
        {
2 , 6 , 8 , NULL},
        {
3 , 0 , 8 , NULL},
        {
3 , 4 , 7 , NULL},
        {
3 , 7 , 9 , NULL},
        {
4 , 0 , 7 , NULL},
        {
4 , 1 , 2 , NULL},
        {
4 , 7 , 1 , NULL},
        {
4 , 8 , 5 , NULL},
        {
5 , 1 , 4 , NULL},
        {
5 , 4 , 1 , NULL},
        {
5 , 8 , 7 , NULL},
        {
6 , 2 , 7 , NULL},
        {
6 , 3 , 8 , NULL},
        {
6 , 6 , 9 , NULL},
        {
7 , 1 , 9 , NULL},
        {
7 , 3 , 3 , NULL},
        {
7 , 5 , 1 , NULL},
        {
8 , 1 , 8 , NULL},
        {
8 , 3 , 7 , NULL},
        {
8 , 4 , 5 , NULL},
        {
8 , 5 , 9 , NULL},
        {
8 , 8 , 4 , NULL},
        {
0 , 0 , 0 , ( struct  item  * 1 }
    };

int  main()
{
    CGroupMap  gm;
    
struct  item  *  first  =  NULL;
    
struct  item  *  tmp  =  itArra ;
    
struct  item  *  cur  =  NULL ;
    
struct  item  *  it ;
    
while (tmp -> next  ==  NULL)
    {
        it 
=  ( struct  item  *  )  new  item;
        
* it  =   *  tmp;

        
if (first  ==  NULL) {
            first 
=  it ;
            cur 
=  it;
        } 
else  {
            cur
-> next  =  it;
            cur 
=  it;
        }
        tmp 
++ ;
    }

    gm.InitMap(first);
    
// gm.DumpPossible();
    gm.StartCal();
    gm.Show();
    
return   0 ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值