筆試題——數獨游戲實現


轉載請注明: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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM