poj2676(数独)

也是一个简单剪枝的dfs。记录所有为0的位置,依次填写,当发现某个空格可选的填写数字已经没有时,说明该支路无效,剪掉。

不算是一个难题吧,但是还是花了不少时间,问题主要出在细节上,行列坐标反了、3乘3小格的位置判断等。写程序一定要细心。

#include <iostream>
using namespace std;

const int MAX_R = 9;
int map[MAX_R + 1][MAX_R + 1];
int zero_pos[MAX_R * MAX_R][2];
int possible_digits[MAX_R * MAX_R][9];
int zero_cnt;

int setPossibleDigits(int x, int y, int s)
{
    bool possible[10];
    memset(possible, 0, sizeof(possible));
    for (int i = 1; i <= MAX_R; i++){
        possible[map[i][x]] = true;
        possible[map[y][i]] = true;
    }
    int subX = (x - 1) / 3;
    int subY = (y - 1) / 3;
    for (int i = subX * 3 + 1; i <= subX * 3 + 3; i++){
        for (int j = subY * 3 + 1; j <= subY * 3 + 3; j++){
            possible[map[j][i]] = true;
        }
    }
    int cnt = 0;
    for (int i = 1; i <= 9; i++){
        if (!possible[i])
            possible_digits[s][cnt++] = i;
    }
    return cnt;
}

bool dfs(int step)
{
    if (step == zero_cnt){
        return true;
    }
    int curX = zero_pos[step][1],
        curY = zero_pos[step][0];
    int possible_cnt = setPossibleDigits(curX, curY, step);
    if (possible_cnt == 0){
        return false;
    }
    for (int i = 0; i < possible_cnt; i++){
        map[curY][curX] = possible_digits[step][i];
        if (dfs(step + 1))
            return true;
        else
            map[curY][curX] = 0;
    }
    return false;
}

int main()
{
    int t;
    cin >> t;
    while (t--){
        memset(map, 0, sizeof(map));
        memset(zero_pos, 0, sizeof(zero_pos));
        memset(possible_digits, 0, sizeof(possible_digits));
        zero_cnt = 0;
        for (int i = 1; i <= MAX_R; i++){
            for (int j = 1; j <= MAX_R; j++){
                char ch;
                cin >> ch;
                map[i][j] = ch - ‘0‘;
                if (map[i][j] == 0){
                    zero_pos[zero_cnt][0] = i;
                    zero_pos[zero_cnt++][1] = j;
                }
            }
        }
        dfs(0);
        for (int i = 1; i <= MAX_R; i++){
            for (int j = 1; j <= MAX_R; j++){
                cout << map[i][j];
            }
            cout << endl;
        }
    }
    return 0;
}
时间: 2024-10-27 11:36:36

poj2676(数独)的相关文章

poj2676(数独 搜索)

题目链接 题意 解出N个9x9的数独,(输出一个解即可) 解题思路 用一个二维布尔数组来标记,点(x,y)的行,列,块的数字是否已经出现过,然后直接暴力搜索即可 AC代码 #include<vector> #include<algorithm> #include<cstdio> #include<iostream> #include<set> #include<cstring> #include<functional> #

POJ2676 Sudoku [数独]

好题,也很实用,犯了几个错误 1.在枚举赋值的时候,思维有个错误:当当前的赋值不能填完这个数独,应该是继续下一个循环,而不是return false 终止枚举 2.Generic Programing写错了,,,本来那个memset想写成Generic Programing的,,,然后,永远只有第一组结果对 不说了,泪哈,,, #include <cstdio> #include <cstring> #include <iostream> #include <cs

POJ--2676&amp;HDU--1421(数独,dfs)

Sudoku Time Limit: 2000MS   Memory Limit: 65536KB   64bit IO Format: %I64d & %I64u Submit Status Description Sudoku is a very simple task. A square table with 9 rows and 9 columns is divided to 9 smaller squares 3x3 as shown on the Figure. In some of

POJ2676 Sudoku - DFS

POJ2676 Sudoku 传送门 题意: 填充未完成的数独...(就这么简单.... 思路: 爆搜即可. 可行性剪枝:用三个\(bool\)数组分别记录行.列.\(3*3\)的块中,\(9\)种数字的使用情况 AC Code: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=9+10; char s[N][N];int mp[N][N];

第二次作业——个人项目实战:数独

1.阅读 刚开始泛看<构建之法>的时候,还是觉得非常难理解里面的内容,特别是代码部分.后来第二次拿起这本书,从第一章开始看起,慢慢了解了"软件企业=软件+商业模式"和对软件工程的定义,但是更多地还是记忆了一遍,没有明白这里面的深意:看第二章的时候,跟着单元测试.回归测试的.效能分析的内容自己照着书上的代码敲了一敲,偶尔会出现bug,但是能得到书上所说的效果还是很开心的,效能分析,感觉就是代码的效率问题,追求高效,然后接触到了软件工程师的一套模型-个人开发流程PSP,我也尝试

洛谷 【P1074】靶形数独

P1074 靶形数独 题目描述 小城和小华都是热爱数学的好学生,最近,他们不约而同地迷上了数独游戏,好胜的他 们想用数独来一比高低.但普通的数独对他们来说都过于简单了,于是他们向 Z 博士请教, Z 博士拿出了他最近发明的“靶形数独”,作为这两个孩子比试的题目. 靶形数独的方格同普通数独一样,在 9 格宽×9 格高的大九宫格中有 9 个 3 格宽×3 格 高的小九宫格(用粗黑色线隔开的).在这个大九宫格中,有一些数字是已知的,根据这些数字,利用逻辑推理,在其他的空格上填入 1 到 9 的数字.每

#计算机#数独

数独是一项益智小游戏,规则简单易懂,但内容千变万化.这次我想要研究的是用java编程实现解数独和数独题目的生成.首先要弄清数独的游戏规则:在一个9×9的方格中分布着1-9的数字和空格,玩家在空格中填写适当的数字,使得每行.每列.9个3×3的方格中数字1-9均只出现一次. 对于解数独初步构思的时候我产生了两种想法: 第一种想法利用计算机强大的运算能力,遍历当前空格所有可以填入的数字,向后递归,当某个空格不能填入数字,而空格数不为零时返回上一步.如果某一步只能填入一个确定的数字,可以把这一步优先填好

安卓旅途之——开发数独(一)

安卓旅途之——开发数独(一) 数独游戏简介 数独游戏,是一种数学智力拼图游戏,是“独立的数字游戏”的简称,源自18世纪末的瑞士,后在美国发展,在日本得以发扬光大. 数独游戏可以训练玩家的逻辑推理能力,不少教育者皆认为数独是锻炼脑筋的好方法. 其规则如下: 1.游戏会从一个部分带有数字的九宫格开始. 在9×9的大九宫格(即3格宽×3格高)方阵里,每一格又细分为一个小九宫格. 2.游戏开始,已给定若干数字,其它宫位留白,玩家需要自己按照逻辑推敲出剩下的空格里是什么数字. 3.填数字时必须满足以下条件

使用AxureRP7.0制作经典数独小游戏原型,axure游戏原型下载

之前,有同学在Q群中提问,如何使用axure制作经典数独解谜小游戏,当时由于时间关系没有来得及亲手制作,而是给同学们提供了Axure6.5版本的一个数独解谜游戏的原型,本教程由axure原型库网站录制,转载请注明出处!但是那个原型做的太过繁杂,所以仅供大家参考交流:在此,金乌老师特地抽时间给同学们使用AxureRP7.0制作了一下,感觉对实战逻辑分析和axure变量的掌握比较有考验,所以就放出来供大家学习交流使用. 在学习的过程中,如果你仅凭自己现有的对axure的掌握,无法准确分析并组织出原型