数独程序
来源:互联网 发布:mysql联表查询效率 编辑:程序博客网 时间:2024/05/22 14:59
//
// su.h
// sudo
//
// Created by thw on 2017/8/8.
// Copyright © 2017年 thw. All rights reserved.
//
#ifndef su_h
#define su_h
#include <stack>
#include <iostream>
/*
int sudo[9][9] = {
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,
};
*/
/*
int sudo[9][9]={
0,1,0,0,0,3,0,5,0,
3,0,0,0,0,5,0,0,2,
0,0,0,8,0,0,0,1,0,
7,0,8,0,3,0,1,2,0,
2,9,0,0,0,0,0,7,3,
0,3,6,0,2,0,4,0,5,
0,7,0,0,0,2,0,0,0,
6,0,0,4,0,0,0,0,7,
0,2,0,9,0,0,0,6,0};
*/
int sudo[9][9] = {
8,0,0,0,0,0,0,0,0,
0,0,3,6,0,0,0,0,0,
0,7,0,0,9,0,2,0,0,
0,5,0,0,0,7,0,0,0,
0,0,0,0,4,5,7,0,0,
0,0,0,1,0,0,0,3,0,
0,0,1,0,0,0,0,6,8,
0,0,8,5,0,0,0,1,0,
0,9,0,0,0,0,4,0,0,
};
std::stack<int> stack[9][9];//当前sudo上行列位置上可填数字栈
//sudo坐标左右小九格偏移
int gLeft[9] = {0,1,2,0,1,2,0,1,2};
int gRight[9] = {2,1,0,2,1,0,2,1,0};
//sudo坐标上下小九格偏移
int gTop[9] = {0,1,2,0,1,2,0,1,2};
int gBottom[9] = {2,1,0,2,1,0,2,1,0};
//搜索pos路径
typedef struct _Pos
{
int i;
int j;
std::stack<int> values;
}Pos;
std::stack<Pos> posStack;
void printSudo()
{
for (int i =0; i< 9; i++){
for (int j =0; j < 9 ;j++){
std::cout<<sudo[i][j];
if ((j+1) %3 ==0){
std::cout<<"|";
}
else{
std::cout<<" ";
}
}
std::cout <<std::endl;
if ((i+1)%3==0) {
for (int j =0; j < 9 ;j++){
std::cout<<"- ";
}
std::cout <<std::endl;
}
}
std::cout <<std::endl;
}
bool okSudo()
{
for (int i =0; i< 9; i++){
for (int j =0; j < 9 ;j++){
if (sudo[i][j] ==0)
returnfalse;
}
}
returntrue;
}
void clearStack(int i,int j)
{
while (!stack[i][j].empty()) {
stack[i][j].pop();
}
}
//获取si,sj位置上的可填数字栈
void getStack(int si,int sj)
{
int temparr[10] = {0,1,2,3,4,5,6,7,8,9};
//移除对应的大九宫格行列上数字
for (int j =0; j< 9; j++){
temparr[sudo[si][j]] =0;
}
for (int i =0; i< 9; i++){
temparr[sudo[i][sj]] =0;
}
//移除小九宫格内对应数字
int left =gLeft[sj];
int right =gRight[sj];
int top =gTop[si];
int bottom =gBottom[si];
int min_x = si-top;
int min_y = sj-left;
int max_x = si+bottom;
int max_y = sj+right;
for (int i = min_x; i <= max_x;i++){
for (int j = min_y; j <= max_y;j++)
temparr[sudo[i][j]] =0;
}
//可填数字入栈
for (int i =1; i < 10; i++){
if (temparr[i] !=0){
stack[si][sj].push(temparr[i]);
}
}
}
bool backOldPos()
{
while (!posStack.empty()){
Pos& backPos =posStack.top();
if (backPos.values.empty()){
//此位置已无可填数字,回退上一个位置
sudo[backPos.i][backPos.j] =0;
posStack.pop();
}
else{
//回退一个可填数字
sudo[backPos.i][backPos.j] = backPos.values.top();
backPos.values.pop();
returntrue;
}
}
//路径完毕,表示无解了
returnfalse;
}
static int placeNewPosCnt =0;
bool placeNewPos()
{
placeNewPosCnt++;
//设置后面所有新可填位置的数字堆栈
for (int i =0; i< 9; i++){
for (int j =0; j < 9 ;j++){
if (sudo[i][j] ==0){
clearStack(i, j);
getStack(i,j);
}
}
}
//找一个新可填位置,策略:找可填数字最少的新位置
Pos curPos;
int minLen =10;
for (int i =0; i< 9; i++){
for (int j =0; j < 9 ;j++){
if (sudo[i][j] ==0 && !stack[i][j].empty() &&stack[i][j].size()<minLen){
curPos.i = i;
curPos.j = j;
minLen = (int)stack[i][j].size();
}
}
}
if (minLen ==10){
//无新位置可设置
returnfalse;
}
//找到新位置,新位置填一个数字,此位置其他可填数字入位置栈,待回溯时调用
sudo[curPos.i][curPos.j] =stack[curPos.i][curPos.j].top();
stack[curPos.i][curPos.j].pop();
while (!stack[curPos.i][curPos.j].empty()){
curPos.values.push(stack[curPos.i][curPos.j].top());
stack[curPos.i][curPos.j].pop();
}
posStack.push(curPos);
returntrue;
}
void killSudo()
{
while (placeNewPos()){
;//往前找,直到无法找到可填数字
}
if (okSudo())
{
std::cout<<"ok,placeNewPos count : " << placeNewPosCnt <<std::endl;
printSudo();
return;
}
//回溯路径
if (!backOldPos()){
std::cout<<"failed"<<std::endl;
printSudo();
return;
}
//回溯一个数字后,继续递归往前找
killSudo();
}
#endif /* su_h */
- “数独”程序
- 数独求解程序
- 数独游戏程序
- 数独判断程序
- 数独程序
- 数独程序
- 计算数独的小程序-.-
- 数独(sudoku)游戏的程序求解
- 数独(Sudoku)求解程序
- Matlab 求解数独的程序
- dancing links-数独的程序解决方案
- LeetCode Sudoku Solver 数独C++程序
- 一个随机生成数独的程序
- 数独游戏的程序算法
- 数独程序 Hodoku 的汉化
- 数独解题程序的JAVA实现
- 数独求解程序 php版
- 结对项目-数独程序扩展
- 12. Integer to Roman
- 屏幕适配完美解决方案
- Java 由今天往前推7天怎么算
- 彻底理解java语言的线程安全volatile用法
- linux shell 字符串替换
- 数独程序
- 2016年7个最佳的Java框架
- SQL总结(二)连表查询
- vb.net 数组列表详解
- Unity 中的声音系统
- Hadoop Shell 命令
- javascript-表单操作
- Android SDK Manager中需要安装的内容
- webpack中mainifest.js vendor.js app.js 三者的区别