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. HDU 5074 Hatsune Miku(DP)

    Problem Description Hatsune Miku is a popular virtual singer. It is very popular in both Japan and C ...

  2. iOS UICollectionView 入门 07 点击cell放大图片

    这一节,我们实现通过点击图片将图片放大显示的功能. 首先我们创建一个名为FlickrPhotoViewConroller的类,这个类继承于UIViewController. 改动头文件内容例如以下: ...

  3. 查看Linux主机CPU及内存信息

    查看CPU信息(型号)  # cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c        8  Intel(R) Xeon(R) CPU ...

  4. iOS UIView 基本属性用法

    .创建UIView UIView * redView = [[UIView alloc] initWithFrame:CGRectMake(, , , )]; UIView * blueView = ...

  5. iOS开发——高级技术&广告功能的实现

    广告功能的实现 iPhone/iPad的程序,即使是Free的版本,也可以通过广告给我们带来收入.前提是你的程序足够吸引人,有足够的下载量.这里,我将介绍一下程序中集成广告的方法.主要有两种广告iAd ...

  6. HDU 3157 Crazy Circuits(有源汇上下界最小流)

    HDU 3157 Crazy Circuits 题目链接 题意:一个电路板,上面有N个接线柱(标号1~N),还有两个电源接线柱 + -.给出一些线路,每一个线路有一个下限值求一个能够让全部部件正常工作 ...

  7. [原创]如何写好SqlHelper

    所有写数据库应用的都会遇到SqlHelper.每个人实现的也不同,网上现成的例子也很多.但在实际操作中,大部分都不实用.什么样的才是实用的?答:适合应用场景的! 下面来介绍下我写的一个关于Oracle ...

  8. html5中viewport使用

    html5中viewport使用 转载自:http://www.maoegg.com/the-usage-of-viewport-in-html5/ 用html5开发移动应用时往往会遇到手机的分辨率或 ...

  9. tar备份系统

    一.概述 前几天我通过SSH正在调戏汤姆猫(tomcat)的时候,服务器上CentOS突然挂了.开机grub,使用光盘linux rescue修复提示找不到linux分区,然后想mount硬盘备份系统 ...

  10. com.ulitis.www

    package com.ulitis.www; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io ...