C++實(shí)現(xiàn)數(shù)獨(dú)快速求解
什么是數(shù)獨(dú)
數(shù)獨(dú)是源自18世紀(jì)瑞士的一種數(shù)學(xué)游戲。是一種運(yùn)用紙、筆進(jìn)行演算的邏輯游戲。玩家需要根據(jù)9×9盤面上的已知數(shù)字,推理出所有剩余空格的數(shù)字,并滿足每一行、每一列、每一個(gè)粗線宮(3*3)內(nèi)的數(shù)字均含1-9,不重復(fù)。
數(shù)獨(dú)盤面是個(gè)九宮,每一宮又分為九個(gè)小格。在這八十一格中給出一定的已知數(shù)字和解題條件,利用邏輯和推理,在其他的空格上填入1-9的數(shù)字。使1-9每個(gè)數(shù)字在每一行、每一列和每一宮中都只出現(xiàn)一次,所以又稱“九宮格”。
解決思路
1、遍歷數(shù)獨(dú)表,找出數(shù)字為空(以0填充)的表格;
2、找出每個(gè)數(shù)據(jù)中空的表格中可以填充的數(shù)字;
3、找到其中可以填充的數(shù)字個(gè)數(shù)最少的表格;
4、將每個(gè)數(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;
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C語(yǔ)言中隊(duì)列的結(jié)構(gòu)和函數(shù)接口的使用示例
隊(duì)列只允許一端進(jìn)行插入數(shù)據(jù)操作,在另一端進(jìn)行刪除數(shù)據(jù)操作的特殊線性表,隊(duì)列具有先進(jìn)先出FIFO的性質(zhì);隊(duì)列可用數(shù)組和鏈表 的方法實(shí)現(xiàn),使用鏈表的結(jié)構(gòu)實(shí)現(xiàn)更優(yōu)一些,因?yàn)槿绻褂脭?shù)組節(jié),出隊(duì)列時(shí)刪去首元素需要將整個(gè)數(shù)組前移,效率比較低2023-02-02
C語(yǔ)言游戲項(xiàng)目球球大作戰(zhàn)實(shí)現(xiàn)流程
這篇文章主要為大家詳細(xì)介紹了如何用C語(yǔ)言實(shí)現(xiàn)流行游戲球球大作戰(zhàn),文中示例代碼介紹的非常詳細(xì),如果過(guò)程中有問(wèn)題在文末還有視頻講解,感興趣的小伙伴們可以參考一下2022-01-01
C++11標(biāo)準(zhǔn)庫(kù) 互斥鎖 <mutex> 詳解
這篇文章主要介紹了C++11標(biāo)準(zhǔn)庫(kù)互斥鎖 <mutex> 的相關(guān)知識(shí),使用call_once()的時(shí)候,需要一個(gè)once_flag作為call_once()的傳入?yún)?shù),本文給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-07-07
C++動(dòng)態(tài)內(nèi)存分配超詳細(xì)講解
給數(shù)組分配多大的空間?你是否和初學(xué)C時(shí)的我一樣,有過(guò)這樣的疑問(wèn)。這一期就來(lái)聊一聊動(dòng)態(tài)內(nèi)存的分配,讀完這篇文章,你可能對(duì)內(nèi)存的分配有一個(gè)更好的理解2022-08-08
c++函數(shù)指針和回調(diào)函數(shù)示例
這篇文章主要介紹了c++函數(shù)指針和回調(diào)函數(shù)示例,需要的朋友可以參考下2014-05-05

