#include <iostream>#include <algorithm>#include <cstring>#include <cstdio>#include <cstdlib>////#define INPUT///#define DBG/** Problem: HDU2780 - Su-Su-Sudoku Begin Time: 19th/Mar/2012 17:52 End Time: 19th/Mar/2012 20:04 Test Data: 基本上範例過了就過了 Standard output: See upstair Knowledge Point: DFS + 回溯 + 狀態是否合法判斷的一個小Trick Thought: 總體思路就是:在第5個空上挨個填一個數字,如果行的話就輸出,如果不行的話回溯到上一層遞迴試試其他數字。直到所有數字全試完了為止 但是這裡有幾個小tricks Trick1:開了一個numOfDigits數組用來記錄1-9每個數字出現了幾次,只有出現小於9次的數字我們才往空裡填,剪枝策略1 Trick2:開了一個blockState數組,用來判斷每個3x3的小數獨中每個數字是否都出現過,與一個全1數組memcmp比較就可以得到結果了 不過注意blockState有一個0,所以sucBlock = {0,1,1,1...}; Trick3:對於大數獨的每行/每列都放入一個數組中排序之後與sucState比較,如果是0,1,2,3,4,5,6,7,8,9則代表符合,否則不符合 Notice:我們把maze(大數獨)數組的[0]行和[0]列都放棄不用了,所以要有一個前置0 Experience: 輸出格式請注意!最後一行不用輸出額外的分行符號了,一定要仔細審題!! Presentation Error + 2 還有數組一定要記得初始化,blockState因為沒初始化貢獻了WA Wrong Answer + 1*/using namespace std;struct node{ int x; int y;};const int sucBlock[10] = {0,1,1,1,1,1,1,1,1,1};const int sucState[10] = {0,1,2,3,4,5,6,7,8,9};int maze[10][10];node unknowPoint[5];int numOfDigits[10];//bool isFound;int comp(const void* a,const void* b){ return ( *(int*)a - *(int*)b );}bool checkBlock(int x,int y){ int blockState[10]; memset(blockState,0,sizeof(int)*10); for(int i = x ; i < x + 3; i++) { for(int j = y; j < y + 3 ; j++) { blockState[maze[i][j]]++; } } if( memcmp(blockState,sucBlock,sizeof(int)*10) != 0 ) { return false; } return true;}bool check(){#ifdef DBG printf("Debuging..Checking this maze :\n"); for(int i = 1 ; i <= 9 ; i++) { for(int j = 1 ; j <= 9 ; j++) { printf("%d ",maze[i][j]); } printf("\n"); }#endif int checkState[10]; for(int i = 1; i <= 9 ; i++) { ///比較橫行 memcpy(checkState,maze[i],sizeof(maze[i])); qsort(checkState,10,sizeof(int),comp); if ( memcmp(checkState,sucState,sizeof(int)*10) != 0 ) { return false; } } checkState[0] = 0; for(int i = 1; i <= 9 ; i++) { ///比較豎行 for(int j = 1 ; j <= 9 ; j++) { checkState[j] = maze[j][i]; } qsort(checkState,10,sizeof(int),comp); if( memcmp(checkState,sucState,sizeof(int)*10 ) != 0) { return false; } } for(int i = 1; i <= 7 ; i = i + 3) { for(int j = 1; j <= 7 ; j = j + 3 ) { if(!checkBlock(i,j)) { return false; } } }#ifdef DBG printf("The res is true\n");#endif return true;}bool Solve(int index){ if ( index > 4 ) { return check(); } for( int i = 1; i <= 9 ; i++) { if( numOfDigits[i] < 9) { numOfDigits[i]++; maze[unknowPoint[index].x][unknowPoint[index].y] = i; if ( Solve(index+1) ) { return true; } maze[unknowPoint[index].x][unknowPoint[index].y] = 0; numOfDigits[i]--; } } return false;}int main(){ int t,k,n; char tmp[50];#ifdef INPUT freopen("b:\\acm\\hdu2780\\input.txt","r",stdin);#ifdef DBG freopen("b:\\acm\\hdu2780\\dbg.txt","w",stdout);#endif#endif while ( scanf("%d",&t) != EOF) { // n = 0; //isFound = false; // gets(tmp); //scanf("%s",tmp); for(k = 0 ; k < t ; k++) { n = 0; memset(maze,0,sizeof(maze)); memset(tmp,0,sizeof(tmp)); memset(numOfDigits,0,sizeof(numOfDigits)); for(int i = 1 ; i <= 9 ; i++) { scanf("%s",tmp); for(int j = 1; j <= 9 ; j++) { // scanf("%d",&maze[i][j]); maze[i][j] = tmp[j-1] - '0'; if ( maze[i][j] == 0 ) { unknowPoint[n].x = i; unknowPoint[n].y = j; n++; } else { numOfDigits[maze[i][j]]++; } } } if ( Solve(0) ) { for(int i = 1 ; i <= 9 ; i++) { for(int j = 1 ; j <=9 ; j++) { printf("%d",maze[i][j]); } printf("\n"); } } else { printf("Could not complete this grid.\n"); } if ( k != t - 1 ) { printf("\n"); } } } return 0;}