数独

数独是一种传统益智游戏,你需要把一个 9×9 的数独补充完整,使得图中每行、每列、每个 3×3 的九宫格内数字 1∼9 均恰好出现一次。

请编写一个程序填写数独。

输入格式
输入包含多组测试用例。

每个测试用例占一行,包含 81 个字符,代表数独的 81 个格内数据(顺序总体由上到下,同行由左到右)。

每个字符都是一个数字(1−9)或一个 .(表示尚未填充)。

您可以假设输入中的每个谜题都只有一个解决方案。

文件结尾处为包含单词 end 的单行,表示输入结束。

输出格式
每个测试用例,输出一行数据,代表填充完全后的数独。

输入样例:
4…8.5.3…7…2…6…8.4…1…6.3.7.5…2…1.4…
…52…8.4…3…9…5.1…6…2…7…3…6…1…7.4…3.
end
输出样例:
417369825632158947958724316825437169791586432346912758289643571573291684164875293
416837529982465371735129468571298643293746185864351297647913852359682714128574936
思路分析:这里我们用一个二进制数来表示每一行每一列所填数的情况,对于某一行和某一列我们一共需要9位二进制数来表示每个位置是否已经填好了数,如果是某个位置上的二进制位为1,则表示这个位置还没有填好数,同时对于每一个九宫格也是如此,对于初始化时我们就每一个位置都初始化为可以填数,然后对于输入进行处理,我们用draw函数进行处理void draw(int x,int y,int t,bool flag){
if(flag)str[xN+y]=‘1’+t;
else str[x
N+y]=’.’;
int v=1<<t;
if(!flag)v=-v;
row[x]-=v;
col[y]-=v;
cell[x/3][y/3]-=v;
}
在这个draw函数中,我们有四个参数,首先是行的位置x,列的位置y,以及当前的数t,以及一个bool类型的变量flag来标记我们能填该数,还是在已经填好该数的位置减去,使得这个位置不填该数,这也是我们在dfs爆搜时的回溯,而在判断某一位上是否是1时,我们可以用二进制中的lowbit运算,能够快速的得到最后一位二进制1,而在dfs时我们怎么样来判断某个位置能填多少个数呢?我们可以用行,列和每一个九宫格对应做与运算即可得到这个状态下可以填的位置数量,对于dfs来说我们可以先搜索节点数目少的分支,所以我们可以先找到这个分支进行搜索

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 9,M=1<<N;
int ones[M],map[M];//用于存储每个状态对应有多少个1,以及对于1<<i映射到i
int row[N],col[N],cell[3][3];//对于每行每列以及每个九宫格能填数的9位二进制状态
char str[100];
void init(){//初始化,将每一个位置均初始化为可以填状态for(int i=0;i<N;i++)col[i]=row[i]=(1<<N)-1;for(int i=0;i<3;i++)for(int j=0;j<3;j++)cell[i][j]=(1<<N)-1;
}
int lowbit(int x)  // 返回末尾的1
{return x & -x;//lowbit运算,非常简单的一个运算
}
void draw(int x,int y,int t,bool flag){if(flag)str[x*N+y]='1'+t;
else str[x*N+y]='.';
int v=1<<t;
if(!flag)v=-v;
row[x]-=v;
col[y]-=v;
cell[x/3][y/3]-=v;
}
int get(int x,int y){return row[x]&col[y]&cell[x/3][y/3];//获得当前状态的函数
}
bool dfs(int cnt){if(!cnt)return true;//如果当前剩下需要填的位置为0,则说明已经找到一组合法的方案int minv=10;int x, y;for (int i = 0; i < N; i ++ )for (int j = 0; j < N; j ++ )if (str[i * N + j] == '.'){int state = get(i, j);if (ones[state] < minv){minv = ones[state];x = i, y = j;}}//剪枝优化,找到需要填的位置最少的分支,从这个分支开始搜索int state=get(x,y);for(int i=state;i;i-=lowbit(i)){int t=map[lowbit(i)];draw(x,y,t,true);if(dfs(cnt-1))return true;draw(x,y,t,false);}return false;
}
int main()
{for(int i=0;i<N;i++)map[1<<i]=i;for(int i=0;i<1<<N;i++)for(int j=0;j<N;j++)ones[i]+=i>>j&1;while (cin >> str, str[0] != 'e'){init();int cnt = 0;for (int i = 0, k = 0; i < N; i ++ )for (int j = 0; j < N; j ++, k ++ )if (str[k] != '.'){int t = str[k] - '1';draw(i, j, t, true);}else cnt ++ ;dfs(cnt);puts(str);}return 0;
}

数独(一道经典的dfs题目)相关推荐

  1. USACO 1.4 Mother's Milk 母亲的牛奶(经典的dfs倒水问题)

    [USACO1.4.4]Mother's Milk 母亲的牛奶 Time Limit:10000MS  Memory Limit:65536K Total Submit:42 Accepted:27  ...

  2. 问题 B: 数独(九宫格经典问题+dfs)

    问题 B: 数独(九宫格经典问题+dfs) 题目描述 这个游戏只有一个规则: 将格子填满使得每一行,每一列,和每一个小的九宫格,恰好包含1-9这9个数字 正是由于规则简单而又变化多端,数独一时间风靡全 ...

  3. 【HDU - 1518】Square (经典的dfs + 剪枝)

    题干: Given a set of sticks of various lengths, is it possible to join them end-to-end to form a squar ...

  4. 一道经典极限题的分析与求解

    一道经典极限题的分析与求解 题目 lim⁡x→∞ex(1+1x)x2\lim_{x\to \infty}\frac{\mathrm{e}^x}{(1+\frac1x)^{x^2}} x→∞lim​(1 ...

  5. 最基础的深度优化搜索(dfs)题目

    最基础的深度优化搜索(dfs)题目 前几天回看自己大一刚开学刷oj时遇到的一道循环类题目,结合这个假期自已学的一点点算法知识,重新写了段代码,也算是加深自己对dfs的理解了. 题目描述 将1,2,⋯, ...

  6. LeetCode刷题——链表OJ(历时三天,万字博客,十一道经典题,带你手撕链表)

    知之愈明,则行之愈笃:行之愈笃,则知之益明. 学完链表,我们不得刷刷题增进对链表的认识?今天博主选取十一道经典链表题,从刷题者的角度剖析重点和易错点,讲解最简单的方法,文章内附题目和题目链接,重点内容 ...

  7. 微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日

    微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日 分类: 天下杂侃 2008-08-07 23:37 17495人阅读 评论(21) 收藏 举报 题目是这样的: 小明和小强 ...

  8. 微软的一道经典逻辑推理题 小明和小强都是张老师的学生,张老师的生日是M月N日

    微软的一道经典逻辑推理题:小明和小强都是张老师的学生,张老师的生日是M月N日 分类: 天下杂侃 2008-08-07 23:37 17495人阅读 评论(21)收藏 举报 题目是这样的: 小明和小强都 ...

  9. 互联网运营面试题_一道经典面试:你认为互联网运营是做什么的?

    成长之"道"写得差不多了,从这篇开始以后多写写"术".今天的主题是一道经典面试:你觉得互联网运营是做什么的? 相信不少读者都遇到过类似的问题,比如你觉得游戏运营 ...

最新文章

  1. android—label窗口——基础编
  2. HDLBits 系列(6)(Reduction)缩位运算符
  3. Leetcode 200 岛屿数量 (每日一题 20210720)
  4. 【数据库设计-3】菜单设计
  5. [Spring]01_环境配置
  6. JVM 类型的生命周期学习
  7. mvc2 mvc_每个人都知道MVC…
  8. cmake编译Debug和Release
  9. [C++] GCC multilib
  10. 在函数‘_start’中:对‘main’未定义的引用
  11. 用php的ob_start()控制浏览器cache
  12. java 爬虫 sessionid_java爬虫实战之模拟登陆
  13. 计算机网络延展-令牌环网
  14. 装了V2.6.41,C4D启动卡死在初始化插件页面,装了RS后C4D无法启动,C4D用什么版本的RS?
  15. 有道智云翻译API + retrofit实现在线翻译Android app
  16. python多条件求和_使用sumifs进行多条件求和
  17. 存储系统结构、MDR、MBR、扇区
  18. Centos上卸载阿里云盾
  19. Esp8266 进阶之路25【高级篇】深聊下esp8266的串口 Uart 通讯中断编程,为您准备好了 NONOS 版本 和 RTOS 系统的串口驱动文件。(附带Demo)
  20. 从会种田到“慧种田”,传感技术成“刚需”!

热门文章

  1. picoCTF2020-Forensics
  2. 计算机网络考前复习知识点(基础)
  3. 餐饮美食菜品推荐数据表
  4. 民安智库开展珠海连锁快餐门店暗访调查
  5. Glow-TTS论文阅读
  6. Asp.Net写入读取Xml(处理文件权限)
  7. 简单操作几步复制保存到卷皮网上多个商品图片
  8. usb server
  9. 2023年湖北省随州市高新技术企业申报材料要求
  10. 【视频文稿】车载Android应用开发与分析 - 开发系统应用