C++實現(xiàn)數(shù)獨(dú)快速求解
什么是數(shù)獨(dú)
數(shù)獨(dú)是源自18世紀(jì)瑞士的一種數(shù)學(xué)游戲。是一種運(yùn)用紙、筆進(jìn)行演算的邏輯游戲。玩家需要根據(jù)9×9盤面上的已知數(shù)字,推理出所有剩余空格的數(shù)字,并滿足每一行、每一列、每一個粗線宮(3*3)內(nèi)的數(shù)字均含1-9,不重復(fù)。
數(shù)獨(dú)盤面是個九宮,每一宮又分為九個小格。在這八十一格中給出一定的已知數(shù)字和解題條件,利用邏輯和推理,在其他的空格上填入1-9的數(shù)字。使1-9每個數(shù)字在每一行、每一列和每一宮中都只出現(xiàn)一次,所以又稱“九宮格”。
解決思路
1、遍歷數(shù)獨(dú)表,找出數(shù)字為空(以0填充)的表格;
2、找出每個數(shù)據(jù)中空的表格中可以填充的數(shù)字;
3、找到其中可以填充的數(shù)字個數(shù)最少的表格;
4、將每個數(shù)字分別填充到該表格中;
5、遞歸重復(fù)步驟1-4,直到表格中不再有數(shù)字為0的表格
#include <iostream>
#include <ctime>
using namespace std;
struct Position
{
? ? int row;
? ? int col;
? ? int *res;
};
Position* findMinBlank(int board[][9])
{
? ? int *validNums(int board[][9], int row, int col);
? ? Position *pos = new Position();
? ? pos->res = 0;
? ? int *res;
? ? int total=0, minum = 10;
? ? for(int i=0; i<9; ++i)
? ? ? ? for(int j=0; j<9; ++j)
? ? ? ? {
? ? ? ? ? ? if(board[i][j]!=0)
? ? ? ? ? ? ? ? continue;
? ? ? ? ? ? res = validNums(board, i, j);
? ? ? ? ? ? total = 0;
? ? ? ? ? ? for(int p=0; p<9; ++p)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? if(res[p]!=0)
? ? ? ? ? ? ? ? {
? ? ? ? ? ? ? ? ? ? ++ total;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? if(total<minum)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? delete []pos->res;
? ? ? ? ? ? ? ? pos->row = i;
? ? ? ? ? ? ? ? pos->col = j;
? ? ? ? ? ? ? ? pos->res = res;
? ? ? ? ? ? ? ? minum = total;
? ? ? ? ? ? }
? ? ? ? ? ? else
? ? ? ? ? ? ? ? delete []res;
? ? ? ? }
? ? return pos;
}
int *validNums(int board[][9], int row, int col)
{
? ? int *res = new int[9] {1,2,3,4,5,6,7,8,9};
? ? for (int i = 0; i < 9; i++)
? ? {
? ? ? ? res[board[row][i]-1] = 0;
? ? ? ? res[board[i][col]-1] = 0;
? ? }
? ? int p = row / 3 * 3;
? ? int q = col / 3 * 3;
? ? for (int x = p; x < p + 3; x++)
? ? ? ? for (int y = q; y < q + 3; y++)?
? ? ? ? {
? ? ? ? ? ? res[board[x][y]-1] = 0;
? ? ? ? }
? ? return res;
}
void printResult(int result[][9] )
{
? ? for (int i = 0; i < 9; i++)?
? ? {
? ? ? ? for (int j = 0; j < 9; j++)?
? ? ? ? {
? ? ? ? ? ? cout << result[i][j] << " ?";
? ? ? ? }
? ? ? ? cout << endl;
? ? }
? ? cout << endl;
}
void sudoku(int board[][9])
{
? ? Position *pos = findMinBlank(board);
? ? if(!pos->res)
? ? {
? ? ? ? cout<<"time:"<<clock()/1e6<<endl;
? ? ? ? printResult(board);
? ? ? ? return;
? ? }
? ? for(int i=0;i<9;++i)
? ? {
? ? ? ? if(pos->res[i]==0)
? ? ? ? ? ? continue;
? ? ? ? board[pos->row][pos->col] = pos->res[i];
? ? ? ? sudoku(board);
? ? }
? ? board[pos->row][pos->col] = 0;
? ? delete pos->res;
? ? delete pos;
}
int main()
{
? ? int start = clock();
? ? cout<<start/1e6<<endl;
? ? int board[][9] =
? ? ? ? {
? ? ? ? ? ? 0, 0, 0, 0, 0, 0, 0, 1, 0,
? ? ? ? ? ? 4, 0, 0, 0, 0, 0, 0, 0, 0,
? ? ? ? ? ? 0, 2, 0, 0, 0, 0, 0, 0, 0,
? ? ? ? ? ? 0, 0, 0, 0, 5, 0, 4, 0, 7,
? ? ? ? ? ? 0, 0, 8, 0, 0, 0, 3, 0, 0,
? ? ? ? ? ? 0, 0, 1, 0, 9, 0, 0, 0, 0,
? ? ? ? ? ? 3, 0, 0, 4, 0, 0, 2, 0, 0,
? ? ? ? ? ? 0, 5, 0, 1, 0, 0, 0, 0, 0,
? ? ? ? ? ? 0, 0, 0, 8, 0, 6, 0, 0, 0
? ? ? ? };
? ? printResult(board);
? ? sudoku(board);
? ? int end = clock();
? ? cout <<"time:" << (end - start)/1e6 << endl;
? ? return 0;
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語言中隊列的結(jié)構(gòu)和函數(shù)接口的使用示例
隊列只允許一端進(jìn)行插入數(shù)據(jù)操作,在另一端進(jìn)行刪除數(shù)據(jù)操作的特殊線性表,隊列具有先進(jìn)先出FIFO的性質(zhì);隊列可用數(shù)組和鏈表 的方法實現(xiàn),使用鏈表的結(jié)構(gòu)實現(xiàn)更優(yōu)一些,因為如果使用數(shù)組節(jié),出隊列時刪去首元素需要將整個數(shù)組前移,效率比較低2023-02-02
C++11標(biāo)準(zhǔn)庫 互斥鎖 <mutex> 詳解
這篇文章主要介紹了C++11標(biāo)準(zhǔn)庫互斥鎖 <mutex> 的相關(guān)知識,使用call_once()的時候,需要一個once_flag作為call_once()的傳入?yún)?shù),本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-07-07
c++函數(shù)指針和回調(diào)函數(shù)示例
這篇文章主要介紹了c++函數(shù)指針和回調(diào)函數(shù)示例,需要的朋友可以參考下2014-05-05

