poj2676(数独 搜索)

题目链接

题意

解出N个9x9的数独,(输出一个解即可)

解题思路

用一个二维布尔数组来标记,点(x,y)的行,列,块的数字是否已经出现过,然后直接暴力搜索即可

AC代码

#include<vector>
#include<algorithm>
#include<cstdio>
#include<iostream>
#include<set>
#include<cstring>
#include<functional>
#include<map>
#include<cmath>
#include<queue>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<int,pii> PII;
bool vis[100][10];
int G[10][10];
int N = 10;
int M = 20;

inline int getid(int& x,int& y)     //得到(x,y)所属的块
{
    if(x<3&&y<3) return M+1;
    else if(x<6&&y<3) return M+2;
    else if(x<9&&y<3)return M+3;
    else if(x<3&&y<6)return M+4;
    else if(x<6&&y<6) return M+5;
    else if(x<9&&y<6) return M+6;
    else if(x<3&&y<9)return M+7;
    else if(x<6&&y<9) return M+8;
    else return M+9;
}

bool ojbk = 0;

void dfs(int x,int y)
{
    if(ojbk)return;
    if(y>8){
        y %= 9;
        x++;
    }
    if(x==9&&y==0){
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                cout << G[i][j];
            }
        }
        ojbk = 1;
    }
    if(G[x][y]){
        dfs(x,y+1);
        return;
    }
    int r = y;
    int c = N+x;
    int id = getid(x,y);
    for(int k=1;k<=9;k++){
        if(vis[r][k]||vis[c][k]||vis[id][k]) continue;
        G[x][y] = k;
        vis[r][k] = 1;
        vis[c][k] = 1;
        vis[id][k] = 1;
        dfs(x,y+1);
        G[x][y] = 0;        //回朔
        vis[r][k] = 0;
        vis[c][k] = 0;
        vis[id][k] = 0;
    }
}

int main(int argc, char const *argv[])
{
    string s;
    while(cin >> s){
        if(s=="end")break;
        ojbk = 0;
        memset(vis,0,sizeof(vis));
        int k = 0;
        for(int i=0;i<9;i++){
            for(int j=0;j<9;j++){
                if(s[k]=='.'){
                    G[i][j] = 0;
                    k++;
                    continue;
                }
                G[i][j] = s[k++]-'0';
                if(G[i][j]==0)continue;
                vis[j][G[i][j]] = 1;
                vis[N+i][G[i][j]] = 1;
                vis[getid(i,j)][G[i][j]] = 1;
            }
        }
        dfs(0,0);
        cout << endl;
    }
    return 0;
}

原文地址:https://www.cnblogs.com/django-lf/p/9763701.html

时间: 2024-10-13 16:18:18

poj2676(数独 搜索)的相关文章

NOIP2009 靶形数独(搜索)

以前做过一道hdu类似的数独题,那道题我没有加什么优化就过了,然后这道题不加优化可以得50~80分,要上80分就必须要优化 可以用位运算保存每一行每一列每个九宫格内已经使用的数,例如userow[i] = 011101111表示第i行还有1,5两个数字没有使用,那么我们枚举每个未知的格子(i,j)时,他不能填的数就是userow[i]|usecol[j]|usebox[i/3*3+j/3] ,其实这样做也不能优化什么时间,下面才是最NB的优化 在输入的时候我们可以统计每一行已知的数,于是我们能够

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 p

noip2009提高组题解

第一题:潜伏者 模拟 注意点: 不同的密文对应的明文不同,反过来,不同的明文对应的密文也不同,我用了两个hash表来实现: 26个明文字母必须有对应的密文字母,我用了两个计数变量来判断是否26个字母都有匹配. ? 第二题:Hankson的趣味题 数论 对 a0, a1, b0, b1 四个数进行质因数分解,然后确定 x 的各质因数的指数的取值范围,运用乘法原理解决.详细分析见下: (引用自http://wenwen.sogou.com/z/q169562042.htm) Gcd(x,a0)=a1

[NOIP2009] 靶形数独(搜索+剪枝)

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

hihoCoder #1321 : 搜索五?数独 (Dancing Links ,精确覆盖)

hiho一下第102周的题目. 原题地址:http://hihocoder.com/problemset/problem/1321 题意:输入一个9*9数独矩阵,0表示没填的空位,输出这个数独的答案. 提示已经讲解的很清楚了.稍微整理下思路.最后附AC代码. 一.Dancing Links解决精确覆盖问题.      1.精确覆盖问题         给定一个n行,m列的01矩阵.从中选择若干行使得每一列有且恰好只有一个1. 例如: 答案是选择2,3,4行. 2.DancingLinks求解精确

POJ2676 Sudoku [数独]

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

【搜索】bzoj3109 [cqoi2013]新数独

搜索,没什么好说的.要注意读入. Code: #include<cstdio> #include<cstdlib> using namespace std; const int num[10][10]= {{0,0,0,0,0,0,0,0,0,0}, {0,1,1,1,2,2,2,3,3,3}, {0,1,1,1,2,2,2,3,3,3}, {0,1,1,1,2,2,2,3,3,3}, {0,4,4,4,5,5,5,6,6,6}, {0,4,4,4,5,5,5,6,6,6}, {0

poj2676 Sudoku(搜索)

题目链接:http://poj.org/problem?id=2676 题意:9*9的方格,0代表没数字,其他代表数字,请在格子中填入1~9的数字,使得在每行,每列和每个3*3的方块中,1~9的数字每个都出现一次. 如果解不唯一输出任意一组即可. 思路:只要满足上诉条件,暴力搜就可以通过了. 代码: #include<iostream> #include<cstring> using namespace std; int mp[10][10]; ///九宫格 int row[10]

搜索 --- 数独求解 POJ 2676 Sudoku

Sudoku Problem's Link:   http://poj.org/problem?id=2676 Mean: 略 analyse: 记录所有空位置,判断当前空位置是否可以填某个数,然后直接DFS,注意从后往前搜索,时间比正向搜快很多.16ms水过 Time complexity: O(n) Source code:  // Memory Time // 1347K 0MS // by : crazyacking // 2015-04-10-14.30 #include<map>