编程之美中构造数独例子

来源:互联网 发布:淘宝店招图片怎么换 编辑:程序博客网 时间:2024/04/29 09:54

编程之美1.15构造数独

生成一个有效的数独矩阵,只生成一个,可以通过递归将所有有效矩阵都构造出来

#include <stdio.h>#include <string.h>#define NO_MOVE0#define AC_MOVE1#define NUM9typedef struct _CELL{int type;int value;int list[NUM];int index;}Cell;typedef struct _POSITION{int x;int y;}Position;Cell m_cells[NUM][NUM];//构造数独的数组void GetValidValueList(Cell *c, Position *p){int row[NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9};//记录行可用数int column[NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9};//记录列可用数int arr[NUM] = {1, 2, 3, 4, 5, 6, 7, 8, 9};//记录小矩阵可用数int i;int j;int tmp;for(i = 0; i < p->x; i++)//遍历行中已经填的数值,并将其设为0{tmp = m_cells[i][p->y].value;row[tmp - 1] = 0;}for(i = 0; i < p->y; i++)//遍历列中已经填的数值,并将其设为0{tmp = m_cells[p->x][i].value;column[tmp - 1] = 0;}for(i = p->x - (p->x % 3); i <= p->x; i++)//遍历小矩阵中已经填的数值,并将其设为0{for(j = p->y - (p->y % 3); j <= p->y - (p->y % 3) + 2; j++){if(i == p->x && j == p->y){break;}tmp = m_cells[i][j].value;arr[tmp - 1] = 0;}}for(i = 0; i < NUM; i++){c->list[i] = row[i] & column[i] & arr[i];//统计总共可用的数}}int PickNextValidValue(Cell *c){int ret;while(c->list[c->index] == 0)//跳过不要用的数0,找到一个可用数{c->index++;if(c->index == NUM){break;}}if(c->index < NUM)//判断是否有有效数{ret = c->list[c->index];}else{ret = -1;}c->index++;//记录下次选数的位置return ret;}void MoveToNextPosition(Position *p)//移动到下一个点{if(p->y == NUM -1){p->y = 0;p->x += 1;}else{p->y += 1;}}void MoveToPrePosition(Position *p){if(p->y == 0){p->y = NUM - 1;p->x -= 1;}else{p->y -= 1;}}void GenerateValidMatrix()//构造数独{Position cur;int value;cur.x = 0;cur.y = 0;while(1){if(m_cells[cur.x][cur.y].type == NO_MOVE)//如果当前点没有生成可用数列表时,生成该列表{GetValidValueList(&m_cells[cur.x][cur.y], &cur);m_cells[cur.x][cur.y].type = AC_MOVE;}value = PickNextValidValue(&m_cells[cur.x][cur.y]);//从可用数列表中选择一个数if(-1 == value)//如果是无效值,退回前一位置{m_cells[cur.x][cur.y].type = NO_MOVE;m_cells[cur.x][cur.y].index = 0;MoveToPrePosition(&cur);}else{m_cells[cur.x][cur.y].value = value;//记录此值if(cur.x == NUM -1 && cur.y == NUM -1)//判断是否结束{break;} else{MoveToNextPosition(&cur);//移动到下一位置}}}}void PrintMatrix()//输出数独矩阵{int i;int j;for(i = 0; i < NUM; i++){if(i % 3 == 0){printf("\n-------------------------------------\n");}else{printf("\n");}for(j = 0; j < NUM; j++){if(j % 3 == 0){printf("|  ");}printf("%d  ", m_cells[i][j].value);}printf("|");}printf("\n-------------------------------------\n");}int main(int argc, char *argv[]){memset(&m_cells, 0, sizeof(m_cells));GenerateValidMatrix();PrintMatrix();return 0;}