grid.h

 #ifndef _GRID_H_
#define _GRID_H_ #include <set>
#include <cstddef> class Grid {
public:
Grid() { for ( int i = ; i < ; i++ ) { value_s.insert(i + ); } } bool set( int value ) {
if ( !contain(value) ) { return false; }
value_s.clear();
value_s.insert(value);
return true;
} size_t size() { return value_s.size(); } int value() {
if ( == size() ) { return *(value_s.begin()); }
return -;
} bool remove(int value) {
value_s.erase(value);
if ( == size() ) { return false; }
return true;
} int value( int index ) {
if ( index >= size() ) { return -; }
std::set<int>::iterator it = value_s.begin();
for ( int i = ; i < index; i++ ) { it ++; }
return *it;
}
private:
std::set<int> value_s; bool contain( int value ) { return ( value_s.end() != value_s.find(value) ); }
}; #endif

sudoku.h

 #ifndef _SUDOKU_H_
#define _SUDOKU_H_ #include "grid.h" struct PosVal {
int i;
int j;
int val;
PosVal( int _i, int _j, int _val ) : i(_i), j(_j), val(_val) {}
bool operator < (const PosVal &pos_val) const {
return ( i == pos_val.i ) ? (j < pos_val.j ) : ( i < pos_val.i );
}
}; struct Result {
int value[][];
bool operator < (const Result &result) const {
for ( int i = ; i < ; i++ ) {
for ( int j = ; j < ; j++ ) {
if (value[i][j] < result.value[i][j]) { return true; }
}
}
return false;
}
}; class Sudoku {
public:
Sudoku() {
for ( int i = ; i < ; i++ ) {
for ( int j =; j < ; j++ ) {
fixed[i][j] = false;
}
}
} bool Init( const std::set<PosVal>& pos_val_s) {
for ( std::set<PosVal>::iterator it = pos_val_s.begin(); it != pos_val_s.end(); it++ ) {
if ( ! set( it->i, it->j, it->val ) ) { return false; }
}
return true;
} void calc( std::set<Result>& result_s ) {
if ( !trim() ) { return; }
if ( all_grid_fixed() ) { fill_result( result_s ); return; }
int i, j;
find_unfixed_min_size_grid(i, j);
for ( int loop = ; loop < size(i, j); loop ++ ) {
Sudoku s( *this );
if ( !s.set(i, j, value(i, j, loop)) ) { return; }
s.calc( result_s );
}
}
private:
Grid grid[][];
bool fixed[][]; bool set(int i, int j, int value) {
if ( !grid[i][j].set(value) ) { return false; }
if ( !trim(i, j, value) ) { return false; }
fixed[i][j] = true;
return true;
} size_t size(int i, int j) { return grid[i][j].size(); } int value(int i, int j ) { return grid[i][j].value(); } int value(int i, int j, int index) { return grid[i][j].value(index); } bool trim(int ii, int jj, int value) {
for (int j = ; j < ; j++) {
if ( j != jj ) { if ( !grid[ii][j].remove(value) ) { return false; } }
}
for (int i = ; i < ; i++) {
if ( i != ii ) { if ( !grid[i][jj].remove(value) ) { return false; } }
}
for (int i = (ii/) * ; i < (ii/) * + ; i++ ) {
for ( int j = (jj/) * ; j < (jj/) * + ; j++ ) {
if ( ( i != ii ) || ( j != jj ) ) { if ( !grid[i][j].remove(value) ) { return false; } }
}
}
return true;
} bool trim() {
bool has_new_fixed_grid = false;
for (int i = ; i < ; i++) {
for (int j = ; j < ; j++) {
if ( !fixed[i][j] && == size(i, j) ) {
has_new_fixed_grid = true;
if ( !set(i, j, value(i, j)) ) { return false; }
}
}
}
if ( has_new_fixed_grid ) { return trim(); }
return true;
} void find_unfixed_min_size_grid(int &ii, int &jj) {
size_t min_size = ;
for (int i = ; i < ; i++ ) {
for ( int j = ; j < ; j++) {
if ( !fixed[i][j] ) {
if ( size(i, j) < min_size ) { ii = i; jj = j; min_size = size(i, j); }
}
}
}
} bool all_grid_fixed() {
for ( int i = ; i < ; i++ ) {
for ( int j = ; j < ; j++ ) {
if ( !fixed[i][j] ) { return false; }
}
}
return true;
} void fill_result( std::set<Result>& result_s ) {
Result result;
for ( int i = ; i < ; i++ ) {
for ( int j = ; j < ; j++ ) {
result.value[i][j] = value(i, j);
}
}
result_s.insert( result );
}
}; #endif

main.cpp

 #include "sudoku.h"
#include <iostream> int main() {
std::set<PosVal> pos_val_s;
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , ));
pos_val_s.insert(PosVal(, , )); Sudoku s;
if ( !s.Init( pos_val_s ) ) {
return -;
} std::set<Result> result_s;
s.calc( result_s );
for ( std::set<Result>::iterator it = result_s.begin(); it != result_s.end(); it++ ) {
for ( int i = ; i < ; i++ ) {
for ( int j = ; j < ; j++ ) {
std::cout << it->value[i][j] << " ";
}
std::cout << std::endl;
}
}
}

数独的C++解法的更多相关文章

  1. 算法实践——舞蹈链(Dancing Links)算法求解数独

    在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dancing Links)算法求解精确覆盖问题. 本文介绍该算法的实际运用,利用舞蹈链(Dancin ...

  2. 创建随机的9x9数独游戏终盘并打印

    创建随机的9x9数独游戏终盘并打印 项目github地址 1. 项目相关要求 1.1 要求 利用程序随机构造出N个已解答的9x9数独棋盘 . 输入 数独棋盘题目个数N(0<N<=10000 ...

  3. 转载 - 算法实践——舞蹈链(Dancing Links)算法求解数独

    出处:http://www.cnblogs.com/grenet/p/3163550.html 在“跳跃的舞者,舞蹈链(Dancing Links)算法——求解精确覆盖问题”一文中介绍了舞蹈链(Dan ...

  4. Leetcode 笔记 36 - Sudoku Solver

    题目链接:Sudoku Solver | LeetCode OJ Write a program to solve a Sudoku puzzle by filling the empty cells ...

  5. 算法练习LeetCode初级算法之数组

    删除数组中的重复项 官方解答: 旋转数组 存在重复元素 只出现一次的数     官方解答:  同一个字符进行两次异或运算就会回到原来的值 两个数组的交集 II import java.util.Arr ...

  6. 36、有效的数独 | 算法(leetode,附思维导图 + 全部解法)300题

    零 标题:算法(leetode,附思维导图 + 全部解法)300题之(36)有效的数独 前言 1)码农三少 ,一个致力于 编写极简.但齐全题解(算法) 的博主. 2)文末附赠 价值上百美刀 资料. 一 ...

  7. [LeetCode] Sudoku Solver 求解数独

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

  8. [LeetCode] Valid Sudoku 验证数独

    Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could be ...

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

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

随机推荐

  1. 关于NoSQL数据库你应该知道的10件事

    关系数据库模型已经流行了几十年了,但是一种新类型的数据库——被称为NoSQL,正在引起企业的注意.下面是关于它的优势和劣势的一个概述.二十多年以来,对数据库管理来说,关系数据库(RDBMS)模型一直是 ...

  2. UIWebView 获取html标题

    使用uiwebview.delegate -(void)webViewDidFinishLoad:(UIWebView *)webView { m_labTitle.text=[m_webVie st ...

  3. windows消息钩子

    1.消息钩子的概念: Windows应用程序是基于消息驱动的,不论什么线程仅仅要注冊窗体类都会有一个消息队列用于接收用户输入的消息和系统消息.为了拦截消息,Windows提出了钩子的概念.钩子(Hoo ...

  4. 关于expanded一级二级菜单数据的分组排序

    最新再弄关于expandedlistview相关的东西,所以需求是需要对一级菜单根据时间排序,同时二级菜单也需要根据时间排序,距离现在最近的时间显示在最前面. 效果就是如下: --group2  -- ...

  5. Config the Android 5.0 Build Environment

    In this document Choosing a Branch    Setting up a Linux build environment        Installing the JDK ...

  6. SQL Server查询所有的表名/空间占用量/行数

    select object_name(id) tablename, 8*reserved/1024 reserved, rtrim(8*dpages)+'kb' used, 8*(reserved-d ...

  7. pomelo 服务器开发常用术语

    gate服务器 一个应用的gate服务器,一般不参与rpc调用,也就是说其配置项里可以没有port字段,仅仅有clientPort字段,它的作用是做前端的负载均衡.客户端往往首先向gate服务器发出请 ...

  8. windows MySQL 5+ 服务手动安装

    一.手动安装mysql 1.准备一个mysql免安装版本(把原来安装好的版本复制一份即可.一次安装多次使用^_^),将mysql复制到指定目录. 2.配置my.ini文件(本例使用的是5.0.22版本 ...

  9. Qt中使用QProcess备份和恢复Mysql数据库

    分类: Qt2011-02-18 21:35 1395人阅读 评论(3) 收藏 举报 qtmysql数据库windowspathcmd . 使用Qt做MySQL数据库开发,遇到需要备份.还原数据库的问 ...

  10. Oracle批量加注释,并生成html

    excel连接列名生成oracle注释 notes: A2为列名,B2为注释 ="comment on column ColAgreementHeader."&A2& ...