数独暴力遍历代码

还是递归大法好。

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#define CELL_DEEP        3
#define MATRIX_DEEP      9
#define MATRIX_NUM      (MATRIX_DEEP*MATRIX_DEEP)
#define FULL_BITMAP     0x1FF

#define TEST_BITMAP(bitmap, bit)       (bitmap) & (1 << (bit))

int GET_BIT_NUM(int bitmap, int *last_bit)
{
    int bit_num = 0;
    int i;

    for(i = 0; i < MATRIX_DEEP; i++)
    {
        if(TEST_BITMAP(bitmap, i))
        {
            if(NULL != last_bit) *last_bit = i;
            bit_num++;
        }
    }

    return bit_num;
}

int BITMAP_TO_STR(int bitmap, char *buffer)
{
    int i, j;

    if(NULL == buffer) return -1;

    for(i = 0, j = 0; i < MATRIX_DEEP; i++) {
        if(TEST_BITMAP(bitmap, i)) {
            buffer[j++] = ‘1‘ + i;
        }
    }
    buffer[j] = 0;

    return 0;
}

#define CLEAR_BITMAP(node, bit)   (node.bitmap) &= ~(1 << (bit)) //0-8

#define CHECK_BITMAP(node)     do {         int last_bit;         if(GET_BIT_NUM(node.bitmap, &last_bit) == 1)         node.value = last_bit + 1;     }while(0)

int my_init_data1[] =
{
    0, 6, 0, 0, 0, 3, 0, 7, 0,
    0, 0, 0, 0, 1, 5, 0, 0, 3,
    0, 7, 9, 0, 2, 0, 0, 5, 0,
    0, 0, 3, 8, 0, 2, 0, 0, 7,
    4, 0, 8, 0, 3, 0, 5, 0, 2,
    6, 0, 0, 5, 0, 1, 9, 0, 0,
    0, 5, 0, 0, 6, 0, 7, 8, 0,
    7, 0, 0, 1, 5, 0, 0, 0, 0,
    0, 3, 0, 2, 0, 0, 0, 4, 0
};

int my_init_data2[] =
{
    0, 7, 0, 0, 5, 0, 0, 6, 0,
    4, 0, 0, 9, 0, 3, 0, 0, 1,
    0, 0, 8, 0, 0, 0, 3, 0, 0,
    0, 5, 0, 0, 0, 0, 0, 4, 0,
    1, 0, 0, 0, 0, 0, 0, 0, 9,
    0, 2, 0, 0, 0, 0, 0, 1, 0,
    0, 0, 4, 0, 0, 0, 7, 0, 0,
    9, 0, 0, 1, 0, 7, 0, 0, 6,
    0, 8, 0, 0, 3, 0, 0, 5, 0
};

int my_init_data3[] =
{
    0, 0, 0, 0, 0, 0, 0, 2, 0,
    0, 3, 0, 0, 0, 9, 0, 0, 6,
    0, 0, 1, 0, 4, 7, 0, 0, 0,
    0, 0, 0, 1, 0, 0, 4, 7, 0,
    0, 0, 5, 0, 0, 0, 3, 0, 0,
    0, 2, 7, 0, 0, 8, 0, 0, 0,
    0, 0, 0, 5, 3, 0, 8, 0, 0,
    8, 0, 0, 2, 0, 0, 0, 6, 0,
    0, 1, 0, 0, 0, 0, 0, 0, 0,
};

int my_init_data[] =
{
    0, 0, 0, 0, 0, 0, 2, 5, 0,
    0, 0, 0, 0, 8, 9, 0, 0, 7,
    0, 0, 0, 2, 0, 0, 0, 0, 8,
    0, 0, 4, 0, 6, 0, 0, 1, 0,
    0, 6, 0, 9, 0, 4, 0, 3, 0,
    0, 7, 0, 0, 2, 0, 5, 0, 0,
    2, 0, 0, 0, 0, 6, 0, 0, 0,
    3, 0, 0, 5, 1, 0, 0, 0, 0,
    0, 8, 9, 0, 0, 0, 0, 0, 0,
};

typedef struct tagNODE_INFO_ST
{
    int value; // 0 means not sure
    int bitmap;
}NODE_INFO_ST;

NODE_INFO_ST my_node_db[MATRIX_NUM];

#if 1 // common
int get_init_data()
{
    int  i;
    char ch;

    printf("\n input initial data(y/n): ");
    scanf("%c", &ch);
    if ( ch != ‘y‘ ) return 0;

INPUT_REP:
    for(i = 0; i < MATRIX_DEEP; i++) {
        printf("line %d: ", i + 1);
        scanf("%d %d %d %d %d %d %d %d %d",
            &my_init_data[i*MATRIX_DEEP], &my_init_data[i*MATRIX_DEEP+1], &my_init_data[i*MATRIX_DEEP+2],
            &my_init_data[i*MATRIX_DEEP+3], &my_init_data[i*MATRIX_DEEP+4], &my_init_data[i*MATRIX_DEEP+5],
            &my_init_data[i*MATRIX_DEEP+6], &my_init_data[i*MATRIX_DEEP+7], &my_init_data[i*MATRIX_DEEP+8]);
    }

    for(i = 0; i < MATRIX_NUM; i++) {
        if(my_init_data[i] < 0 || my_init_data[i] > MATRIX_DEEP) {
            printf("illegal data of %d, try again\n", i);
            goto INPUT_REP;
        }
    }

    return 0;
}

int init_node_db(NODE_INFO_ST *node_db, int *init_data)
{
    int i;

    assert(node_db != NULL);
    assert(init_data != NULL);

    for(i=0; i < MATRIX_NUM; i++) {
        if (init_data[i] > MATRIX_DEEP || init_data[i] < 0) return -2;

        if(init_data[i] > 0) {
            node_db[i].value = init_data[i];
            node_db[i].bitmap = 1 << (init_data[i] - 1);
        } else {
            node_db[i].value = 0;
            node_db[i].bitmap = FULL_BITMAP;
        }
    }

    return 0;
}

int show_init_data(int *init_data)
{
    int i;

    assert(init_data != NULL);

    printf("init data: \n");
    for(i = 0; i < MATRIX_NUM; i++) {
        printf("%d ", init_data[i]);
        if((i+1)%MATRIX_DEEP == 0)printf("\n");
    }
    return 0;
}

int get_all_checked_num(NODE_INFO_ST *node_db)
{
    int checked_num = 0;
    int i;

    assert(node_db != NULL);

    for(i = 0; i < MATRIX_NUM; i++) {
        if (node_db[i].value > 0) {
            checked_num++;
        }
    }

    return checked_num;
}

int get_all_bit_num(NODE_INFO_ST *node_db)
{
    int bit_num = 0;
    int i;

    assert(node_db != NULL);

    for(i = 0; i < MATRIX_NUM; i++) {
        bit_num += GET_BIT_NUM(node_db[i].bitmap, NULL);
    }

    return bit_num;
}

int show_sub_node_db(int line, NODE_INFO_ST *node_db)
{
    int i;
    char buffer[16];

    assert(node_db != NULL);

    printf("sub node db: ", line);
    for(i = 0; i < MATRIX_DEEP; i++) {
        if (node_db[i].value > 0) {
            printf("<==%d==> ", node_db[i].value);
       } else {
            BITMAP_TO_STR(node_db[i].bitmap, buffer);
            printf("%7s ", buffer);
        }
    }
    printf("\n");

    return 0;
}

int show_node_db(int line, NODE_INFO_ST *node_db)
{
    int i;
    char buffer[16];

    assert(node_db != NULL);

    printf("node db: line(%d) checked(%d)\n", line, get_all_checked_num(node_db));
    for(i = 0; i < MATRIX_NUM; i++) {
        if (node_db[i].value > 0) {
            printf("<==%d==> ", node_db[i].value);
       } else {
            BITMAP_TO_STR(node_db[i].bitmap, buffer);
            printf("%7s ", buffer);
        }
        if((i+1)%MATRIX_DEEP == 0)printf("\n");
    }

    return 0;
}

int load_sub_node_db(int mode, NODE_INFO_ST *node_db, int i, NODE_INFO_ST* sub_list)
{
    int j, k, row;
    int cell_x, cell_y;

    assert(node_db != NULL);
    assert(sub_list != NULL);

    if(mode == 1) // row(i)
    {
        for (j = i*MATRIX_DEEP, k = 0; j < i*MATRIX_DEEP + MATRIX_DEEP; j++) {
            memcpy(&sub_list[k++], &node_db[j], sizeof(NODE_INFO_ST));
        }
    }
    else if (mode == 2) // col(i)
    {
        for (j = i, k = 0; j < MATRIX_NUM; j+= MATRIX_DEEP) {
            memcpy(&sub_list[k++], &node_db[j], sizeof(NODE_INFO_ST));
        }
    }
    else if (mode == 3) // cell(i)
    {
        cell_x = (i/CELL_DEEP)*CELL_DEEP;
        cell_y = (i%CELL_DEEP)*CELL_DEEP;
        for(row = 0, k = 0; row < CELL_DEEP; row++) {
                for (j = (cell_x + row)*MATRIX_DEEP + cell_y; j < (cell_x + row)*MATRIX_DEEP + cell_y + CELL_DEEP; j++) {
                    memcpy(&sub_list[k++], &node_db[j], sizeof(NODE_INFO_ST));
                }
            }
    }

    return 0;
}

int restore_sub_node_db(int mode, NODE_INFO_ST *node_db, int i, NODE_INFO_ST* sub_list)
{
    int j, k, row;
    int cell_x, cell_y;

    assert(node_db != NULL);
    assert(sub_list != NULL);

    if(mode == 1) // row(i)
    {
        for (j = i*MATRIX_DEEP, k = 0; j < i*MATRIX_DEEP + MATRIX_DEEP; j++) {
            memcpy(&node_db[j], &sub_list[k++], sizeof(NODE_INFO_ST));
        }
    }
    else if (mode == 2) // col(i)
    {
        for (j = i, k = 0; j < MATRIX_NUM; j+= MATRIX_DEEP) {
            memcpy(&node_db[j], &sub_list[k++], sizeof(NODE_INFO_ST));
        }
    }
    else if (mode == 3) // cell(i)
    {
        cell_x = (i/CELL_DEEP)*CELL_DEEP;
        cell_y = (i%CELL_DEEP)*CELL_DEEP;
        for(row = 0, k = 0; row < CELL_DEEP; row++) {
                for (j = (cell_x + row)*MATRIX_DEEP + cell_y; j < (cell_x + row)*MATRIX_DEEP + cell_y + CELL_DEEP; j++) {
                    memcpy(&node_db[j], &sub_list[k++], sizeof(NODE_INFO_ST));
                }
            }
    }

    return 0;
}
#endif

#if 1 // try
int check_sub_node_db(NODE_INFO_ST* sub_list)
{
    int i, j;

    assert(sub_list != NULL);

    // 检查是否存在节点取值冲突
    for(i = 0; i < MATRIX_DEEP; i++) {
        for (j = 0; j < MATRIX_DEEP; j++) {
            if(j != i && sub_list[i].value > 0 && sub_list[i].value == sub_list[j].value)
                return 1;
        }
    }

    return 0;
}

int check_node_db(NODE_INFO_ST *node_db)
{
    int i, ret = 0;
    NODE_INFO_ST sub_node_db[MATRIX_DEEP];

    assert(node_db != NULL);

    for(i = 0; i < MATRIX_DEEP; i++)
    {
        load_sub_node_db(1, node_db, i, sub_node_db);
        ret = check_sub_node_db(sub_node_db);
        restore_sub_node_db(1, node_db, i, sub_node_db);
        if (ret != 0) return ret;
    }

    for(i = 0; i < MATRIX_DEEP; i++)
    {
        load_sub_node_db(2, node_db, i, sub_node_db);
        ret = check_sub_node_db(sub_node_db);
        restore_sub_node_db(2, node_db, i, sub_node_db);
        if (ret != 0) return ret;
    }

    for(i = 0; i < MATRIX_DEEP; i++)
    {
        load_sub_node_db(3, node_db, i, sub_node_db);
        ret = check_sub_node_db(sub_node_db);
        restore_sub_node_db(3, node_db, i, sub_node_db);
        if (ret != 0) return ret;
    }    

    return 0;
}

int try_node_db(int index, NODE_INFO_ST *node_db)
{
    int i;
    int bitmap_bak;
    NODE_INFO_ST new_node_db[MATRIX_NUM];

    assert(node_db != NULL);
    if (index >= MATRIX_NUM) return 0;

    if (node_db[index].value > 0)
        return try_node_db(index + 1, node_db);

    bitmap_bak = node_db[index].bitmap;
    for(i = 0; i < MATRIX_DEEP; i++)
    {
        if ( TEST_BITMAP(bitmap_bak, i) )
        {
            //printf("try node %d with value %d \n", index + 1, i + 1);
            memcpy(new_node_db, node_db, MATRIX_NUM*sizeof(NODE_INFO_ST));
            new_node_db[index].bitmap = 1 << i;
            new_node_db[index].value = i + 1;

            //check if conflict
            if ( check_node_db(new_node_db) > 0 )
            {
                continue; //not good
            }
            else
            {
                if (get_all_checked_num(new_node_db) == MATRIX_NUM) {
                    printf("try success\n");
                    memcpy(my_node_db, new_node_db, MATRIX_NUM*sizeof(NODE_INFO_ST));
                    return 0;
                }

                if ( 0 == try_node_db(index + 1, new_node_db) )
                    return 0;
            }
        }
    }

    return 1;
}

#endif

int main()
{
    int i,j;
    int temp[MATRIX_DEEP];

    // get init data
    get_init_data();
    show_init_data(my_init_data);

    // generate node db
    init_node_db(my_node_db, my_init_data);
    show_node_db(__LINE__, my_node_db);

#if 0
    // scan
    printf("scan...\n");
    scan_node_db_rep(my_node_db);
    show_node_db(__LINE__, my_node_db);
    if (get_all_checked_num(my_node_db) == MATRIX_NUM)
        goto PASS_CHECK;
#endif

    // try
    printf("try...\n");
    try_node_db(0, my_node_db);
    show_node_db(__LINE__, my_node_db);

PASS_CHECK:
    if (check_node_db(my_node_db) == 0)  printf("DONE.\n");
    else printf("ERROR.\n");

    return 0;
}
时间: 2024-10-14 11:24:13

数独暴力遍历代码的相关文章

数独暴力破解代码(code by unity)

using System.Collections.Generic;using UnityEditor;using UnityEngine; public class testSudo{ class SudokuItem { public bool isNormal = false; //固定数字 不需要检测期望值 public int value; //该item存的值 public List<int> expectValueList; //该item是否可用1-9 1:可用 0:不可用 }

数独破解c++代码

数独破解c++代码 #include <iostream> #include <cstring> #include <cstdio> #include <stack> using namespace std; int grup_start[9][2] = { {0,0} ,{0,3}, {0,6} , {3,0} ,{3,3}, {3,6} , {6,0} ,{6,3}, {6,6} }; int get_grup(int x,int y) { return

数独_erlang解题代码

前几天LP玩数独,玩到大师级各种被虐,我看了看说,分分钟帮你做出来, 结果当然没有做出来. 于是上网搜了下数独的解题代码,看了下C的代码,大多是递归之类的(如http://blog.sina.com.cn/s/blog_9e16dc4d01013s1y.html) 于是想想,这种方法能不能用erlang实现呢? 尝试了一下,发现不行,因为2维数组,指针什么的在erlang完全没有,而且变量不变,所有要换个思路,既然erlang能够并发,那就并发的去填 sd_one是使用唯一填入法和隐式唯一填入法

C#Winform版之CheckBox、ChecklistBox控件遍历代码

CheckBox,是各种开发语言环境和网页中常用的控件.下面,本文给大家讲解的是C#Winform版的CheckBox.控件遍历.全选.反选实例代码.①直接引用如果窗体form中存在CheckBox控件,直接引用的方法为:控件名称.属性=属性值例子:checkBox1.Checked = true;②遍历引用遍历引用有两种情况,其一为checkBox控件不包含在任何容器内:其二是checkBox控件包含于某些容器内.A:checkBox不包含在任何容器内的遍历方法 foreach(Control

数独项目--关键代码展示:

关键代码展示: //判断该数字在当前数独是否符合要求 int judge(int num, int ple){ int x = ple / 9; //x表示数字的纵坐标 int y = ple % 9; //y表示数字的横坐标 int qulx = x / 3; int quey = y / 3;     //que表示9宫格的区域 for (int i = 0; i < 9; i++){ if (map[x][i] == num){ return 0; } } for (int i = 0;

数独暴力猜解

思路 验证已填格子是否合法,非法则回 false 选一个空格子,如果没有空格子则返回 true 对空格子进行填数,依次尝试 1-9 猜解剩余格子,重复步骤 1 步骤 4 猜解成功则返回 true,否则回到步骤 3 尝试下一个填数 1-9 均返回 false,则返回 false 实现 约定 使用 9 x 9 的二维数组存储所有格子 每个格子维护一个可填数的 mask,采用 bitmap 方式存储,所以 0b111_111_111 可填 1-9,0b000_000_000 无可填数 为其中一个格子填

QTP基本循环正常遍历(代码方式实现)

0 环境 系统环境:win7 1 操作(正常遍历篇) 1.1 代码前看 systemutil.Run "D:\Program Files (x86)\HP\QuickTest Professional\samples\flight\app\flight4a.exe" dialog("Login").WinEdit("Agent Name:").Set DataTable("username", dtLocalSheet) di

P1041 传染病控制——暴力遍历所有相同深度的节点

P1041 传染病控制 说实话这种暴力我还是头一次见,每次病毒都会往下传染一层: 数据范围小,我们可以直接枚举当前层保护谁就好了: 用vector 记录相同层数的节点:维护已经断了的点: 如果超出最底层或者都已经被保护就更新答案: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; const int maxn=1010; v

二叉搜索树的先序中序后序非递归遍历代码

#include<iostream>#include<stack>#include<vector>using namespace std;struct node{  int val;  node *left,*right;  node(int _val):val(_val),left(NULL),right(NULL){     } };struct bignode{ bool isfirst;  node* pnode; };void postorder(node*