- 论坛徽章:
- 0
|
不知道大家玩过数独没,这是我做的一个解数独得代码.
新建一个文本文档,名字叫 Sudo.txt
里面的内容如下(下面这个数字矩阵):
0 3 0 0 0 7 0 0 4
6 0 2 0 4 1 0 0 0
0 5 0 0 3 0 9 6 7
0 4 0 0 0 3 0 0 6
0 8 7 0 0 0 3 5 0
9 0 0 7 0 0 0 2 0
7 1 8 0 2 0 0 4 0
0 0 0 1 6 0 8 0 9
4 0 0 5 0 0 0 3 0
保存后就可以了,这个矩阵也可以自己改, 0表示未知值.
如果这个数独不止一个解,所有的解都会被打印出来.
下面就是具体代码了,希望大家玩得愉快,有什么问题的话就留个言吧!
- #include <stdio.h>
- #define debug(x) puts(x)
- #define mask 0x1FF
- #define besure(x) (!(x&(x-1)))
- typedef struct sudo {
- int sudo_p[9][9];
- int sudo_set[3][9];
- int sudo_x, sudo_y;
- struct sudo *sudo_next;
- } t_sudo;
- void save(t_sudo **s, t_sudo *p)
- {
- p->sudo_next = (*s);
- *s = p;
- }
- t_sudo *load(t_sudo **s)
- {
- t_sudo *p = *s;
-
- if (!s || !(*s))
- return NULL;
- (*s) = p->sudo_next;
- return p;
- }
- int hex_to_int(int i)
- {
- int j = 0;
-
- if (i == 0)
- return 0;
-
- if (besure(i)) {
- j = 1;
- while (!(i & 0x1)) {
- i >>= 1;
- j++;
- }
- }
- return j;
- }
- int Sudo_show (char *msg, t_sudo *s, FILE *fp)
- {
- int i, j, count = 0;
-
- while (s) {
- count ++;
- if (msg) {
- fputs(msg, fp);
- fputs("\n", fp);
- }
-
- for (i = 0; i < 9; ++i) {
- for (j = 0; j < 9; ++j)
- fprintf(fp, "%d ", hex_to_int(s->sudo_p[i][j]));
- fputs("\n", fp);
- }
- s = s->sudo_next;
- }
- return count;
- }
- int Sudo_init(char const* filename, t_sudo *s)
- {
- FILE *fp;
- int i, j, t;
-
- memset(s, 0, sizeof(t_sudo));
- fp = fopen(filename, "r");
- if (!fp) {
- fprintf(stderr, "File open error!\n");
- return -1;
- }
-
- for (i = 0; i < 9; ++i) {
- for (j = 0; j < 9; ++j) {
- if (fscanf(fp, "%d", &t) != 1) {
- fprintf(stderr, "Scan error in line %d row %d\n", i, j);
- return -1;
- }
- if (t == 0)
- s->sudo_p[i][j] = mask;
- else
- s->sudo_p[i][j] = 1 << (t-1);
- }
- }
-
- fclose(fp);
- Sudo_show("Sudo Init Complete!", s, stdout);
- return 0;
- }
- int sudo_check(t_sudo *s, int *x, int *y)
- {
- int i, j, k, tmp;
-
- for (i = 0, tmp = 0; i < 9; ++i) {
- for (j = 0; j < 9; ++j) {
- if (!besure(s->sudo_p[i][j])) {
- *x = i;
- *y = j;
- return 1;
- }
- tmp |= s->sudo_p[i][j];
- }
-
- if (tmp != mask)
- return 2;
- }
-
- for (k = 0; k < 9; ++k) {
- for (i = (k/3)*3, tmp = 0; i < (k/3)*3+3; ++i)
- for (j = (k%3)*3; j < (k%3)*3+3; ++j)
- tmp |= s->sudo_p[i][j];
-
- if (tmp != mask)
- return 2;
- }
-
- return 0;
- }
- #define zerolowbit(x) (x & (x-1))
- #define lowbit(x) ((x & (x-1)) ^ x)
- #define CLOSE(s, i, j) if (besure(s->sudo_p[i][j])) { \
- s->sudo_set[0][i] &= ~s->sudo_p[i][j]; \
- s->sudo_set[1][j] &= ~s->sudo_p[i][j]; \
- s->sudo_set[2][(i/3)*3+j/3] &= ~s->sudo_p[i][j]; \
- }
- #define CLOSESTACK(s, i, j) if (!besure(s->sudo_p[i][j])) { \
- s->sudo_p[i][j] &= s->sudo_set[0][i]; \
- s->sudo_p[i][j] &= s->sudo_set[1][j]; \
- s->sudo_p[i][j] &= s->sudo_set[2][(i/3)*3+j/3]; \
- if (s->sudo_p[i][j] == 0) {\
- sp = 0; \
- goto load; \
- } \
- if (besure(s->sudo_p[i][j])) { \
- s->sudo_set[0][i] &= ~s->sudo_p[i][j]; \
- s->sudo_set[1][j] &= ~s->sudo_p[i][j]; \
- s->sudo_set[2][(i/3)*3+j/3] &= ~s->sudo_p[i][j]; \
- stack[sp++] = i; \
- stack[sp++] = j; \
- } \
- }
- int Sudo(t_sudo *s)
- {
- int i, j, x, y, ret, k = 0;
- int stack[182];
- int sp = 0;
- t_sudo *t, *head = NULL, *res=NULL;
-
- t = malloc(sizeof(t_sudo));
- *t = *s;
- s = t;
-
- for (i = 0; i < 3; ++i)
- for (j = 0; j < 9; ++j)
- s->sudo_set[i][j] = mask;
-
- for (i = 0; i < 9; ++i) {
- for (j = 0; j < 9; ++j) {
- CLOSE(s, i, j)
- }
- }
-
- for (i = 0; i < 9; ++i) {
- for (j = 0; j < 9; ++j) {
- CLOSESTACK(s, i, j);
- }
- }
-
- while (1) {
- while (sp != 0) {
- y = stack[--sp];
- x = stack[--sp];
- for (i = 0; i < 9; ++i) {
- CLOSESTACK(s, i, y);
- CLOSESTACK(s, x, i);
- }
- for (i = (x/3)*3; i < (x/3)*3+3; ++i)
- for (j = (y/3)*3; j < (y/3)*3+3; ++j)
- CLOSESTACK(s, i, j);
- }
-
- ret = sudo_check(s, &i, &j);
- if (ret == 0) {
- s->sudo_next = res;
- res = s;
- goto notfreeload;
- } else if (ret == 2) {
- goto load;
- }
- t = malloc(sizeof(t_sudo));
- *t = *s;
- t->sudo_x = i;
- t->sudo_y = j;
- t->sudo_p[i][j] = zerolowbit(t->sudo_p[i][j]) ;
- save(&head, t);
- s->sudo_p[i][j] = lowbit(s->sudo_p[i][j]) ;
- CLOSE(s, i, j);
- stack[sp++] = i;
- stack[sp++] = j;
- continue;
- load:
- free(s);
- notfreeload:
- s = load(&head);
- if (!s) {
- break;
- }
- CLOSE(s, s->sudo_x, s->sudo_y);
- }
-
- k = Sudo_show("-----------------", res, stdout);
- printf("-----------------\n%d result(s) Found!\n", k);
-
- while(res) {
- s = res->sudo_next;
- free(res);
- res = s;
- }
- }
- int main()
- {
- t_sudo p;
-
- Sudo_init("Sudo.txt" , &p);
- Sudo(&p);
-
- system("pause");
- return 0;
- }
复制代码
[ 本帖最后由 xxandxx 于 2007-5-29 09:56 编辑 ] |
|