項目需求:利用程序隨機構造N個已解答的數獨棋盤ios
輸入:數獨棋盤題目個數N (0 < N <= 1000000)面試
輸出:隨機生成N個不重複的已解答完畢的數獨棋盤, 並輸出到sudotiku.txt,每一個數獨棋盤中間隔一行架構
#include<iostream> #include<cstdlib> #include<ctime> #include<fstream> using namespace std; ofstream ocout; int sudo[9][9]; bool set(int x,int y,int val) { if(sudo[x][y]!=0) //非空 return false; int x0,y0; for(y0=0;y0<9;y0++) //行衝突 { if(sudo[x][y0]==val) return false; } for(x0=0;x0<9;x0++) //列衝突 { if(sudo[x0][y]==val) return false; } for(x0=x/3*3;x0<x/3*3+3;x0++) //格衝突 { for(y0=y/3*3;y0<y/3*3+3;y0++) { if(sudo[x0][y0]==val) return false; } } sudo[x][y]=val; return true; } void current(int* cur) ///0~9隨機序列 { int i,j,temp; for(int i=0;i<9;i++) { cur[i]=i; } for(int i=0;i<9;i++) { j=rand()%9; temp=cur[j]; cur[j]=cur[i]; cur[i]=temp; } } void reset(int x,int y) { sudo[x][y]=0; } bool fill(int x,int val) { int cur[9]; current(cur); //生成當前行的掃描序列 for(int i=0;i<9;i++) { int y=cur[i]; if(set(x,y,val)) //能夠先把每一行的1填了,再填每一行的2...以此類推 { if(x==8) //到了最後一行 { if(val==9||fill(0,val+1)) //當前填9則結束,不然從第一行填下一個數 return true; } else { if(fill(x+1,val)) //下一行繼續填當前數 return true; } reset(x,y); //回溯 } } return false; } void clear(int temp[9][9]) //清空 { for(int i=0;i<9;i++) { for(int j=0;j<9;j++) { temp[i][j]=0; } } } void printsudo() //輸出到屏幕 { for(int x=0;x<9;x++) { (x%3==0)?(cout<<" -----------------------\n "):(cout<<" "); cout<<"| "; for(int y=0;y<9;y++) { cout<<sudo[x][y]<<" "; (y%3==2)?(cout<<"| "):(cout<<""); } cout<<endl; } cout<<" -----------------------\n"<<endl; } void printsudotxt() //輸出到sudotiku.txt { for(int x=0;x<9;x++) { (x%3==0)?(ocout<<" -----------------------\n "):(ocout<<" "); ocout<<"| "; for(int y=0;y<9;y++) { ocout<<sudo[x][y]<<" "; (y%3==2)?(ocout<<"| "):(ocout<<""); } ocout<<endl; } ocout<<" -----------------------\n"<<endl; } int main() { srand((unsigned)time(NULL)); //這個是種子函數 爲rand函數提供不一樣的種子 每次運行程序產生不一樣的隨機數,否則rand函數每次運行程序產生的隨機數都是同樣的 ocout.open("sudotiku.txt"); cout<<"請輸入數獨棋盤題目個數N (0 < N <= 1000000):"<<endl; int N; cin>>N; cout<<"隨機生成"<<N<<"個不重複的已解答完畢的數獨棋盤以下:"<<endl; ocout << "隨機生成"<<N<<"個不重複的已解答完畢的數獨棋盤以下:" << endl; for(int i=0;i<N;i++) { clear(sudo); while(!fill(0,1)); printsudo(); printsudotxt(); } ocout.close(); return 0; }
程序運行結果以下:模塊化
隨機生成3個不重複的已解答完畢的數獨棋盤以下:
-----------------------
| 4 1 7 | 3 8 2 | 9 5 6 |
| 2 9 3 | 6 4 5 | 8 7 1 |
| 6 8 5 | 7 9 1 | 2 4 3 |
-----------------------
| 1 7 6 | 5 3 8 | 4 9 2 |
| 8 2 4 | 9 6 7 | 3 1 5 |
| 3 5 9 | 2 1 4 | 6 8 7 |
-----------------------
| 9 3 1 | 4 5 6 | 7 2 8 |
| 5 6 2 | 8 7 9 | 1 3 4 |
| 7 4 8 | 1 2 3 | 5 6 9 |
-----------------------函數
-----------------------
| 6 7 3 | 1 9 2 | 5 4 8 |
| 2 8 1 | 6 5 4 | 9 7 3 |
| 5 4 9 | 8 7 3 | 2 6 1 |
-----------------------
| 3 9 8 | 4 6 1 | 7 5 2 |
| 4 6 7 | 2 8 5 | 3 1 9 |
| 1 5 2 | 7 3 9 | 4 8 6 |
-----------------------
| 8 2 4 | 3 1 7 | 6 9 5 |
| 7 1 5 | 9 2 6 | 8 3 4 |
| 9 3 6 | 5 4 8 | 1 2 7 |
-----------------------測試
-----------------------
| 3 4 9 | 6 7 8 | 5 2 1 |
| 7 8 1 | 2 4 5 | 9 3 6 |
| 6 2 5 | 3 1 9 | 8 4 7 |
-----------------------
| 8 5 3 | 4 6 2 | 1 7 9 |
| 2 9 7 | 8 5 1 | 4 6 3 |
| 4 1 6 | 9 3 7 | 2 5 8 |
-----------------------
| 1 3 2 | 7 9 4 | 6 8 5 |
| 5 6 8 | 1 2 3 | 7 9 4 |
| 9 7 4 | 5 8 6 | 3 1 2 |
-----------------------spa
經測試,程序能夠正確運行,運行時間也較短。線程
經過這次做業,我不只瞭解了數獨這個遊戲,還對回溯的用法有了更深入的認識,有些平時掌握不牢的知識點,通過程序運行中出現的錯誤,都能進行很好的糾正。完成這個程序,我花了好幾天時間,由於沒有思路,因此只能上網查資料,在以後的運行過程當中,遇到了以下幾個問題:架構設計
1.須要在主函數開頭加srand((unsigned)time(NULL));這個種子函數,爲rand函數提供不一樣的種子,每次運行程序產生不一樣的隨機數,否則rand函數每次運行程序產生的隨機數都是同樣的;debug
2.將程序運行結果輸出到sudotiku.txt,ofstream ocout;語句須要寫在開頭;
3.回溯法的運用,須要理清思路。
這些問題的解決都是經過百度別人的經驗來進行解決的。
我認爲對我特別重要的技能有如下幾項:
1.程序理解(如何理解已有的程序,經過閱讀、分析、debug)
2.架構設計、模塊化設計、接口設計
3.模塊實現、逐步細化
4.效能分析與改進
5.線程之間/進程之間/不一樣平臺的進程之間
6.我的軟件過程:估計、記錄工做量,並逐步提升
目前我具有的專業知識、技能、能力都處於一個基礎階段,掌握了基本的書面知識和實踐技能,但願在學完這門課程後,能夠掌握基本的理論和實踐知識,經過通常相關企業的面試。