数独解法,哈哈,之前有个折磨了好久的题,我写过该解法,拿来改了改即可。
首先,网上有论文支持当已知点的个数小于17是无解的。
然后,暴力即可,暴力的技巧是:从可能性少的开始搜索。
struct Pointxy { int x; int y; int val; }; int cmp(Pointxy a,Pointxy b) { return a.val < b.val; } class Solution { public: int bitarray[9]; int map[9][9]; bool result; int CountOnes(int v) { int number = 0; while(v) { v &= (v-1); number++; } return number; } int GetRegionOfBoard(int x,int y) { if(x>= 0 && x < 3) { if(y >= 0 && y < 3)return 0; if(y >= 3 && y < 6)return 1; if(y >= 6 && y < 9)return 2; } if(x >= 3 && x < 6) { if(y >= 0 && y < 3)return 3; if(y >= 3 && y < 6)return 4; if(y >= 6 && y < 9)return 5;<br /> } if(x >= 6 && x < 9) { if(y >= 0 && y < 3)return 6; if(y >= 3 && y < 6)return 7; if(y >= 6 && y < 9)return 8; } } bool RefeshMap(int x,int y){ int set_tmp = 0; for(int i = 0;i < 9;i++) { if(CountOnes(map[x][i]) == 1) { set_tmp = set_tmp | map[x][i]; } if(CountOnes(map[i][y]) == 1) { set_tmp = set_tmp | map[i][y];<br /> } } int region = GetRegionOfBoard(x,y); int x_r = (region / 3 + 1)<em>3; int y_r = (region % 3 + 1)</em>3; for(int i = x_r-3;i < x_r;i++) { for(int j = y_r-3;j < y_r;j++) { if(CountOnes(map[i][j]) == 1) { set_tmp = set_tmp | map[i][j];<br /> } } } if(set_tmp == 511)return false; map[x][y] = 511 - set_tmp; return true; } void Move(Pointxy pxy[81],int index,vector<vector<char> > &board) { if(result == true)return; if(index <= 0) { result = true; /<em>for(int i = 0;i < 9;i++) { for(int j = 0;j < 9;j++) { printf("%c",board[i][j]); } printf("\n"); }</em>/ return; } else { sort(pxy,pxy+index,cmp); int pi = pxy[0].x; int pj = pxy[0].y; for(int ibit = 0;ibit < 9;ibit++) { if(result == true)return; if(map[pi][pj] & bitarray[ibit]) { if(pi == 0&&pj == 6) { int hujiulin = 1; } board[pi][pj] = ibit+1+'0'; map[pi][pj] -= bitarray[ibit]; int xtmp[81]; int ytmp[81]; int indextmp = 0; for(int i = 1;i < index;i++) { int xi = pxy[i].x; int yi = pxy[i].y; if(xi == pi || yi == pj || GetRegionOfBoard(xi,yi) == GetRegionOfBoard(pi,pj)) { if(map[xi][yi] & bitarray[ibit]) { xtmp[indextmp] = xi; ytmp[indextmp++] = yi; map[xi][yi] -= bitarray[ibit]; } } } Pointxy pxyt[81]; int indext = 0; for(int i = 1;i < index;i++) { pxyt[indext].x = pxy[i].x; pxyt[indext].y = pxy[i].y; pxyt[indext].val = CountOnes(map[pxyt[indext].x][pxyt[indext].y]); indext++; } Move(pxyt,indext,board); for(int i = 0;i < indextmp;i++) { int xi = xtmp[i]; int yi = ytmp[i]; map[xi][yi] += bitarray[ibit]; } map[pi][pj] += bitarray[ibit]; //board[pi][pj] = '.'; } } } } void solveSudoku(vector<vector<char> > &board) { for(int i = 0;i < 9;i++) { bitarray[i] = (int)pow(2.0,i); } int count = 0; for(int i = 0;i < 9;i++) { for(int j = 0;j < 9;j++) { if(board[i][j] == '.') { map[i][j] = 511; } else { map[i][j] = bitarray[board[i][j] - '0'-1]; count++; } } } if(count < 17)return ; Pointxy pxy[81]; int index = 0; for(int i = 0;i < 9;i++) { for(int j = 0;j < 9;j++) { if(map[i][j] == 511) { if(RefeshMap(i,j) == false)return ; pxy[index].x = i; pxy[index].y = j; pxy[index++].val = CountOnes(map[i][j]); } if(CountOnes(map[i][j]) == 1) { int k = 0; for(k = 0;k < 9;k++) { if(map[i][j] == bitarray[k])break; } board[i][j] = k+1+'0'; } } } result = false; Move(pxy,index,board); //return result;</p> <pre><code>} </code></pre> <p>};