轉載請注明:http://www.cnblogs.com/igoslly/p/8708960.html
題目:用戶會輸入數獨預先填好的數字,請設計程序進行解題
輸入:按行按列進行輸入,空置位置以0輸入
數獨游戲要求:
根據表格里先給出的提示,填寫1-9數字,使9×9的宮格滿足每行、每列數字均不重復;同時9×9格盤中9個3×3的小格也必須滿足1-9不重復。
體會一下(圖片來自百度搜索):
思路:
現實解數獨游戲會有大師級的技巧,但是計算機解最直接的方法,那就是窮舉法———某格從1~9嘗試,填寫正確后再進行次格的嘗試,如是往下推理,若遇到某個格子1-9均無法滿足,則返回上級+1
偽代碼大概如下:
dfs(當前判斷位置){ 結束條件: if(已完成)返回 if(當前位置不為0) //題目給定數字
{ dfs(當前判斷位置+1) } else { for(從1到9進行嘗試) { if(如果當前嘗試數i合法) 填寫數字;dfs(當前判斷位置+1); 返回時已填寫完畢,直接返回; } 當前填寫位置=0; } }
int dfs(int n){ // 數獨矩陣已經填完,返回
if(n>80) { sign=true; return 0; } if(num[n/9][n%9]!=0) { // 該格存在規定值,繼續
dfs(n+1); }else{ for(int i=1;i<=9;i++) { // 分別從1開始窮舉,前提是不與填數字矛盾
if(check(n,i)==true){ num[n/9][n%9]=i; dfs(n+1); //如果已完成 直接返回
if(sign==true) return 0; } } // 若該格1-9均無法滿足,則需返回上級dfs // 此時若不置位0,上級dfs會將此格的9,默認為系統輸入,進行報錯
num[n/9][n%9]=0; } }
合法條件判斷:
填寫數字是否合法,是依據同行、同列以及同九宮格進行判斷:
bool check(int n,int key){ // 對於每個n,所在行數n/9,列數n%9 // 檢測同行是否存在相同數
for(int i=0;i<9;i++){ int j=n/9; if(num[j][i]==key) { return false; } } // 檢測同列是否存在相同數
for(int i=0;i<9;i++) { int j=n%9; if(num[i][j]==key){return false;} } // 檢測同矩陣是否存在相同數
int x=n/9/3*3; int y=n%9/3*3; for(int i=x;i<x+3;i++){ for(int j=y;j<y+3;j++){ if(num[i][j]==key){return false;} } } // 均不存在,返回true合法
return true; }
添加輸入、輸出函數后,整體的代碼如下:
#include<iostream>
using namespace std; int num[9][9]={0}; bool sign=false; // 輸入
void input(){ for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ cin>>num[i][j]; } } } // 輸出數獨
void output(){ for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ cout << num[i][j] << " "; if(j%3==2){ cout<<" "; } } cout<<endl; if(i%3==2){ cout<<endl; } } } // 檢測填入數字是否合法
bool check(int n,int key){ // 對於每個n,所在行數n/9,列數n%9 // 檢測同行是否存在相同數
for(int i=0;i<9;i++){ int j=n/9; if(num[j][i]==key) { return false; } } // 檢測同列是否存在相同數
for(int i=0;i<9;i++) { int j=n%9; if(num[i][j]==key){return false;} } // 檢測同矩陣是否存在相同數
int x=n/9/3*3; int y=n%9/3*3; for(int i=x;i<x+3;i++){ for(int j=y;j<y+3;j++){ if(num[i][j]==key){return false;} } } // 均不存在,返回true合法
return true; } int dfs(int n){ // 數獨矩陣已經填完,返回
if(n>80) { sign=true; return 0; } if(num[n/9][n%9]!=0) { // 該格存在規定值,繼續
dfs(n+1); }else{ for(int i=1;i<=9;i++) { // 分別從1開始窮舉,前提是不與填數字矛盾
if(check(n,i)==true){ num[n/9][n%9]=i; dfs(n+1); //如果已完成 直接返回
if(sign==true) return 0; } } // 若該格1-9均無法滿足,則需返回上級dfs // 此時若不置位0,上級dfs會將此格的9,默認為系統輸入,進行報錯
num[n/9][n%9]=0; } } int main(){ //freopen("C://Users//Lly//Desktop//input.txt","r",stdin);
input(); dfs(0); output(); return 0; }
測試結果:
當然數獨游戲還是有更簡便的實現的!
具體可看leetcode鏈接——https://www.cnblogs.com/igoslly/p/8719622.html