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