【4】数独(Sudoku Killer)(深度优先遍历)
时间:2019-03-18
本文章向大家介绍【4】数独(Sudoku Killer)(深度优先遍历),主要包括【4】数独(Sudoku Killer)(深度优先遍历)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
问题描述:给你多个数独题目,让你输出答案
思路:递归确定每一个‘?’的位置的值,直到所有‘?’都被确定。先将原字符数组转换为整型数组,‘?’由数字0代替,然后每一次层递归找到第一个0的位置,如果找到了,找出当前位置所有可以放置的数字,依次尝试,每次假设把这个数放在当前位置,然后再确认下一个0位置的数字,直到数组中找不到0,即是正确结果(递归出口)。
#include <stdio.h> #include <iostream> using namespace std; void coutint(int b[9][9]) //输出整型二维数组 { int i,j; for(i=0;i<9;i++){ for(j=0;j<9;j++) if(j!=8) cout<<b[i][j]<<' '; else cout<<b[i][j]; cout<<endl; } } void char2int(char a[9][20],int b[9][9]) //字符二维数组向整型二维数组转换 { int i,j; for(i=0;i<9;i++) for(j=0;j<18;j++) if(a[i][j]=='?') b[i][j/2] = 0; else if('1'<=a[i][j] && a[i][j]<='9') b[i][j/2] = a[i][j]-'0'; //字符转化为整型 } bool judge(int curx,int cury,int num,const int b[9][9]) { int i,j; //查找一横行 for(i=0;i<9;i++) //将这一行出现的数字全部设为不可填 if(i!=cury && b[curx][i]==num) return true; //查找一竖列 for(i=0;i<9;i++) //将这一行出现的数字全部设为不可填 if(i!=curx && b[i][cury]==num) return true; //查找当前九宫格 int x,y; x = curx/3*3; y = cury/3*3; for(i=0;i<3;i++) for(j=0;j<3;j++) if(x+i!=curx && y+j!=cury && b[x+i][y+j]==num) return true; return false; } bool dfs(int b[9][9]) { //找到当前第一个'?'位置。如果没有找到,表示所有位置都已填上,即为正确结果,递归结束 int i,j; for(i=0;i<9;i++) for(j=0;j<9;j++) if(b[i][j]==0) //找'?'的位置 goto label; label: if(i>=9 && j>=9) //找到正确结果了,递归结束 return true; //记录坐标 int curx = i,cury = j; //确定该位置的可以填的数字 bool temp[10]; //记录哪些数字可以填 int num=0; //记录当前位置可以填的数字的个数 for(i=1;i<=9;i++) if(judge(curx,cury,i,b)) //判断这个位置可不可以放这个数字 temp[i] = false; else { temp[i] = true; num++; } if(num==0) return false; //确定下一个位置 for(i=1;i<=9;i++) if(temp[i]){ //这个数在这个位置可以填 if(judge(curx,cury,i,b)) continue; b[curx][cury] = i; if(dfs(b)) return true; } b[curx][cury] = 0; //这句千万别忘了写,就是这一步不能走的记得还原为0 return false; } int main() { char a[9][20]; int b[9][9]; int i; for(i=0;i<9;i++) cin.getline(a[i],20,'\n'); char2int(a,b); //char数组转换为int数组 if(dfs(b)) //产生结果 coutint(b); //输出数组内容 while(cin.getline(a[0],20,'\n')){ //读取空行,或者到文件尾 cout<<endl; char a[9][20]; int b[9][9]; int i; for(i=0;i<9;i++) cin.getline(a[i],20,'\n'); char2int(a,b); //char数组转换为int数组 if(dfs(b)) //产生结果 coutint(b); //输出数组内容 } return 0; }
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【终端设备】视频上云/网络穿透EasyNTS云组网硬件终端无法单独修改账号的优化方式
- 测试环境问题排查的那些事儿
- RTSP流媒体协议视频平台EasyNVR和EasyNTS智能云组网同一浏览器运行为什么会导致EasyNTS无法登陆?
- Java:手写线程安全LRU缓存X探究影响命中率的因素
- 视频上云/网络穿透/网络映射服务EasyNTS设备管理为什么会出现无法搜索到设备的情况?
- 快速打造属于你的接口自动化测试框架
- 大数据下的质量体系建设
- PostgreSQL 日志系统 及 设置错误导致磁盘塞满案例
- 六、乘胜追击,将剩下的Git知识点搞定
- 树莓派基础实验39:解析无线电接收机PWM、SBUS信号
- nodejs源码分析第十九章 -- udp模块
- Spark Extracting,transforming,selecting features
- 逆向so文件调试工具ida基础知识点
- 二叉搜索树中的众数
- 了解递归:普通函数递归和非递归栈式实现之间的区别