Write a program to solve a Sudoku puzzle by filling the empty cells.

Empty cells are indicated by the character '.'.

You may assume that there will be only one unique solution.

A sudoku puzzle...

...and its solution numbers marked in red.

Hide Tags

Backtracking Hash Table

 

    这题是解数独,这个嘛,我用的是递归写法,简单描述就是填写当前空格,递归下一格,遇到不行返回,不过逻辑写的不好,很多奇奇怪怪的细节的判断。
 
算法逻辑:
  1. 创建一个辅助函数,help(vector<vector<char> > & board,int i,int ii,int j,int jj),其中i为第几行,j 第几列,ii 小框中的第几行,jj 小框中第几列。
  2. help 函数4层for 循环遍历整个9*9 矩阵,说是4层,跟两次for 是一样的,i 和j 的步长是3,for(;i<9;i+=3),因为这4个变量的初始化在函数传入的时候,所以在其循环结束时候尾部赋0,其中一个不好的地方。
  3. 4层循环内部,首先判断当前格board[i+ii][j+jj]是否为数字,不然继续循环。
  4. 创建标记finish = false,标记接下来的填入(当前格为空)能否完成整个矩阵,用于控制跳出填写,和如果填写失败修复当前格为'.' 回溯。
  5. 遍历1-9 尝试填写,需要用到bool canIn=true,判断行,列,框中的情况,如果通过判断则修改当框为遍历的数字,递归下一格,输入当前格的i ii j jj,便可以,这是第二个不好的地方,判断没有写为外部函数,另外函数的参数设置导致了很多细节问题。
  6. 下层返回的值赋予 finish ,如果为false ,表示当前填写不行,继续遍历,如果为true,跳出填写的遍历。
  7. 结束遍历后判断是否已经填写整个矩阵,如果finish 为false,表示失败了,则当前格,然后返回false,成功先别返回。
  8. 外部4层循环结束返回true。

   所以在外层循环后返回true,是假如例子上的情况,最后一个格不为空,那么按上面逻辑是不会进入内部的,而如果能够全部遍历完整个矩阵,那么表示没有在内部返回,等价于成功填写了。

之所以使用 ii jj,是为了可以方便处理3*3框,在能否填写的时候,需要注意跳过自身与自身判断,先判断行列,然后框的时候变可以跳过当前框所在的行列了。

 #include <vector>
#include <iostream>
#include <iterator>
using namespace std; class Solution {
public:
void solveSudoku(vector<vector<char> > &board) {
help(board,,,,);
}
bool help(vector<vector<char> > & board,int i,int ii,int j,int jj){
for(;i<;i+=){
for(;ii<;ii++){
for(;j<;j+=){
for(;jj<;jj++){
if(board[i+ii][j+jj]!='.') continue;
bool finish = false;
for(char c='';c<=''&&!finish;c++){
bool canIn= true;
for(int k=;k<&&canIn;k++){
if(k!=i+ii&&board[k][j+jj]==c) canIn = false;
if(k!=j+jj&&board[i+ii][k]==c) canIn = false;
}
for(int ti=;ti<&&canIn;ti++){
if(ti == ii) continue;
for(int tj=;tj<&&canIn;tj++){
if(tj==jj) continue;
if(board[ti+i][tj+j]==c) canIn = false;
}
}
if(canIn==false) continue;
board[i+ii][j+jj] = c;
finish = help(board,i,ii,j,jj);
}
if(!finish){ board[i+ii][j+jj] = '.'; return false; }
}
jj = ;
}
j=;
}
ii=;
}
return true;
}
}; int main()
{
vector<char> line;
vector<vector<char> > board;
line = {'','','.','.','','.','.','.','.'};
board.push_back(line);
line.clear();
line = {'','.','.','','','','.','.','.'};
board.push_back(line);
line.clear();
line = {'.','','','.','.','.','.','','.'};
board.push_back(line);
line.clear();
line = {'','.','.','.','','.','.','.',''};
board.push_back(line);
line.clear();
line = {'','.','.','','.','','.','.',''};
board.push_back(line);
line.clear();
line = {'','.','.','.','','.','.','.',''};
board.push_back(line);
line.clear();
line = {'.','','.','.','.','.','','','.'};
board.push_back(line);
line.clear();
line = {'.','.','.','','','','.','.',''};
board.push_back(line);
line.clear();
line = {'.','.','.','.','','.','.','',''};
board.push_back(line);
Solution sol;
sol.solveSudoku(board);
for(int i=;i<board.size();i++){
copy(board[i].begin(),board[i].end(),ostream_iterator<char>(cout," "));
cout<<endl;
}
return ;
}
 
 
 
 
 
 
 
 
 

[LeetCode] Sudoku Solver 解数独,递归,回溯的更多相关文章

  1. [leetcode]37. Sudoku Solver 解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy  ...

  2. [LeetCode] Sudoku Solver 求解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  3. 037 Sudoku Solver 解数独

    写一个程序通过填充空格来解决数独.空格用 '.' 表示. 详见:https://leetcode.com/problems/sudoku-solver/description/ class Solut ...

  4. LeetCode:Valid Sudoku,Sudoku Solver(数独游戏)

    Valid Sudoku Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku bo ...

  5. Sudoku Solver, 求数独

    问题描述:填充数独表中空元素.空元素为'.' 算法分析:没填充一个数,都要看这个数所在的行,列,小矩阵是否合法.然后还要看整个数独表是否正确,而判断整个数独表只能通过递归,因为前一个结果的判断要依赖后 ...

  6. [LeetCode] 37. Sudoku Solver 求解数独

    Write a program to solve a Sudoku puzzle by filling the empty cells. A sudoku solution must satisfy  ...

  7. LeetCode OJ:Sudoku Solver(数独游戏)

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

  8. Leetcode: Sudoku Solver

    July 19, 2015 Problem statement: Write a program to solve a Sudoku puzzle by filling the empty cells ...

  9. [LeetCode] Sudoku Solver(迭代)

    Write a program to solve a Sudoku puzzle by filling the empty cells. Empty cells are indicated by th ...

随机推荐

  1. 十一、Shell 输入/输出重定向

    Shell 输入/输出重定向 大多数 UNIX 系统命令从你的终端接受输入并将所产生的输出发送回​​到您的终端.一个命令通常从一个叫标准输入的地方读取输入,默认情况下,这恰好是你的终端.同样,一个命令 ...

  2. windows环境下安装npm、cnpm、bower

    什么是npm.cnpm.bower? 简单地说,就是帮你下载好你需要的css或者js库,而且三者功能也都是一样的.那为什么要下载这3个不同的呢?据说npm容易被墙……而cnpm是淘宝的镜像,所以通常用 ...

  3. JZOJ 1266. 玉米田

    1266. 玉米田(cowfood.pas/c/cpp) (File IO): input:cowfood.in output:cowfood.out Time Limits: 1000 ms  Me ...

  4. (转)curl常用命令

    本文转自 http://www.cnblogs.com/gbyukg/p/3326825.html 下载单个文件,默认将输出打印到标准输出中(STDOUT)中 curl http://www.cent ...

  5. 团体程序设计天梯赛-练习集 L2-001 紧急救援 (25 分)

    作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图.在地图上显示有多个分散的城市和一些连接城市的快速道路.每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上.当其他城市有紧急求 ...

  6. OpenResty安装与hello world

    安装环境:CentOS 7.0 1. 安装编译工具.依赖库 yum -y install readline-devel pcre-devel openssl-devel gcc 2. 下载openre ...

  7. day38--MySQL基础二

    1.数据库连表 1.1, 一对多 使用外键做约束.注意:外键列的数据类型要一致. 命令的方式创建外键CREATE table part1( nid int not null auto_incremen ...

  8. 【清华集训】小Y和地铁

    图已挂,前往luogu 题目: 小 $\rm Y$ 是一个爱好旅行的 $\rm OIer$.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁.她发现每条地铁线路可以看成平面上的一条 ...

  9. IOS开发学习笔记009-OC基本知识

    开始学习OC,时间不等人啊,要抓紧了. OC基本知识 新建一个以.m结尾的文件,这既是oc的程序文件.在oc程序中完全兼容C语言.编译好链接类似. oc包含头文件是使用#import <> ...

  10. 简单实现nodejs爬虫工具

    约30行代码实现一个简单nodejs爬虫工具,定时抓取网页数据. 使用npm模块 request---简单http请求客户端.(轻量级) fs---nodejs文件模块.   index.js var ...