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