九宫格数独游戏解法(一)

最近看这东东比较有意思,写了这个程序。
这是个比较粗略的解法,对于简单的一两次就解掉了,复杂的可能要多运行几次才比较容易得出结果。
这个简单程序最复杂的地方是要把直观上的三种情况得出三个独立的值,然后取交集,尤其是在同一个循环里边实现第三个数组,想了我很久。

// NO.game.cpp : 定义控制台应用程序的入口点。
//
#include <stdio.h>
#include <tchar.h>

#include <string.h>
#include <stdlib.h>

#define MAX_TABLE_LINE (3*3)
int _tmain(int argc, _TCHAR* argv[])
{
    int i = 0, j = 0;
    int content[MAX_TABLE_LINE][MAX_TABLE_LINE];
    // input
    short int x[MAX_TABLE_LINE], y[MAX_TABLE_LINE], z[MAX_TABLE_LINE];
    memset(x, 0, sizeof(x));
    memset(y, 0, sizeof(y));
    memset(z, 0, sizeof(z));
    memset(content, 0, sizeof(content));

    FILE *fp = fopen("content.txt","r");
    for(i = 0; i < MAX_TABLE_LINE; i++)
    {
        for(j = 0; j < MAX_TABLE_LINE; j++)
        {
            fscanf(fp, "%d", &content[i][j]);
        }
    }

    int a =0 , b = 0;
    for(i = 0; i < MAX_TABLE_LINE; i++)
    {
        for(j = 0; j < MAX_TABLE_LINE; j++)
        {
            if(content[i][j] > 0)
                x[i] |= 1<<content[i][j]-1; // 每个空位的横向已经取值集合
            if(content[j][i] > 0)
                y[i] |= 1<<content[j][i]-1; // 每个空位的纵向已经取值集合
            a = (i/3)*3 + j/3;
            b = (i%3)*3 + j%3;
            if(content[a][b] > 0)
                z[i] |= 1<<content[a][b]-1; // 每个空位的田字格内已经取值集合
            printf("(%d,%d)content[%d][%d]=%d content[%d][%d]=%d · a=%d b=%d · x[%d]=%d y[%d]=%d z[%d]=%d\n"
                ,i,j,i,j,content[i][j],j,i,content[j][i],a,b,i,x[i],i,y[i],i,z[i]);
        }
    }

    short int result = 0 ;
    for(i = 0; i < MAX_TABLE_LINE; i++)
        for(j = 0; j < MAX_TABLE_LINE; j++)
        {
            if(content[i][j] > 0)
                printf("         %d",content[i][j]);
            else
            {
                printf(" ");
                result = ~x[i]&~y[j]&~z[(i/3)*3 + j/3]; //  可取值的交集
                for(a = 0; a < 9; a++)
                {
                    printf("%d",(result>>(8-a))&0x0001);
                }
            }
            if(j == MAX_TABLE_LINE-1)
                printf("\n");
        }
    system("pause");
    return 0;
}

测试数据和结果1:(简单)

0 5 2 0 0 6 0 0 0 1 6 0 9 0 0 0 0 4 0 4 9 8 0 3 6 2 0 4 0 0 0 0 0 8 0 0 0 8 3 2 0 1 5 9 0 0 0 1 0 0 0 0 0 2 0 9 7 3 0 5 2 4 0 2 0 0 0 0 9 0 5 6 0 0 0 1 0 0 9 7 0
 011000100         5         2 001001000 001001001         6 001000101 010000101 111000101
         1         6 010000000         9 001010010 001000010 001000100 010000100         4
 001000000         4         9         8 001010001         3         6         2 001010001
         4 001000010 000110000 001110000 101110100 001000000         8 000100101 001000101
 001100000         8         3         2 001101000         1         5         9 001000000
 101110000 001000000         1 001111000 111111100 011001000 001001100 000100100         2
 010100000         9         7         3 010100000         5         2         4 010000001
         2 000000101 010001000 001001000 011001000         9 000000101         5         6
 010110100 000000100 010111000         1 010101010 010001010         9         7 010000100

分析:如上面结果所示,(2,0)、(1,2)、(3,5)、(4,8)、(8,1)等等结果已经得出,其它就容易算出结果了。

 

测试数据和结果2:(困难)

6 0 0 3 0 0 1 0 0 0 7 1 6 2 0 0 0 0 8 0 5 0 0 1 0 0 0 5 0 0 8 7 0 9 0 1 0 0 9 0 0 0 6 0 0 4 0 7 0 6 9 0 0 8 0 0 0 2 0 0 8 0 7 0 0 0 0 8 6 4 1 0 0 0 8 0 0 3 0 0 2
         6 100001010 000001010         3 100011000 011011000         1 111011010 100011000
 100000100         7         1         6         2 010011000 000010100 110011100 100011100
         8 100001110         5 101001000 100001000         1 001000110 101101110 100101100
         5 000100110 000100110         8         7 000001010         9 000001110         1
 000000111 010000111         9 000011001 000011101 000011010         6 001011110 000011100
         4 000000111         7 000010001         6         9 000010110 000010110         8
 100000101 100111101 000101100         2 100011001 000011000         8 100110100         7
 101000110 100010110 000000110 101010000         8         6         4         1 100010100
 101000001 100111001         8 101011001 100011001         3 000010000 100110000         2

结果分析:这个比较难第一次运算只能得出一个值(8,6)即5,下面还需进一步运算。。。

 

在算法中主要体现的是集合的概念和运算,如交并集的处理。
在困难里边还有一个比较难以实现的数据,假如在一组(即9个)数据中有三个值分别为:100001000、100001000、110001000。可以得出结果第三个数必为8。

程序仅供学习参考,有高手请指教!!!

posted @ 2012-11-29 01:22  upendi  Views(7643)  Comments(0Edit  收藏  举报