做题的时候看到这道题就直接放弃了,毕竟现实生活中的我就不怎么会填数独。
再一次觉得洛谷题解的强大。
简单易懂
#include<iostream> #include<cstdio> using namespace std; int MAP[10][10]= { 0,0,0,0,0,0,0,0,0,0, 0,1,1,1,2,2,2,3,3,3, 0,1,1,1,2,2,2,3,3,3, 0,1,1,1,2,2,2,3,3,3, 0,4,4,4,5,5,5,6,6,6, 0,4,4,4,5,5,5,6,6,6, 0,4,4,4,5,5,5,6,6,6, 0,7,7,7,8,8,8,9,9,9, 0,7,7,7,8,8,8,9,9,9, 0,7,7,7,8,8,8,9,9,9 }; int q[10][10]= { 0,0,0,0,0,0,0,0,0,0, 0,6,6,6,6,6,6,6,6,6, 0,6,7,7,7,7,7,7,7,6, 0,6,7,8,8,8,8,8,7,6, 0,6,7,8,9,9,9,8,7,6, 0,6,7,8,9,10,9,8,7,6, 0,6,7,8,9,9,9,8,7,6, 0,6,7,8,8,8,8,8,7,6, 0,6,7,7,7,7,7,7,7,6, 0,6,6,6,6,6,6,6,6,6 }; int fangzheng[10][10]; bool x[10][10];//行,x[i][j]表示第几行的用了哪个数 bool y[10][10];//列,y[i][j]表示第几列用了哪个数 bool cube[10][10];//宫,哪个宫中的哪个数被用了 int ans=0; int t1=0,t2=0; int sum() ///当前生成数独的权值和 { int tmp=0; for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) { tmp+=fangzheng[i][j]*q[i][j]; } return tmp; } void dfs1(int i,int j) ///从右下角开始 { if(fangzheng[i][j]) ///已经填数了 { if(i==1 && j==1)//已经是最后一个空了 { ans=max(ans,sum());//对当前的权值和最佳解进行比对 return; } else//如果没有到 { if(j==1) dfs1(i-1,9);//如果找到当前这一行的最后一个空 else dfs1(i,j-1); ///不是就继续搜下一个 } } else ///如果没填数 { for(int k=1;k<=9;k++) ///填个数 if(!x[i][k] && !y[j][k] && !cube[MAP[i][j]][k])//如果这个数在当前的宫,行,列都没有填过 { fangzheng[i][j]=k;//不妨试一试 x[i][k]=true;//将行,列,宫标记为用过 y[j][k]=true; cube[MAP[i][j]][k]=true; if(j-1<1)//如果是当行的最后一个 { if(i-1<1) ///如果已经是(1,1) { ans=max(ans,sum()); fangzheng[i][j]=0; x[i][k]=false; y[j][k]=false; cube[MAP[i][j]][k]=false; return;//算一下,随便再复原 } else dfs1(i-1,9);//不是就继续找下一行 } else dfs1(i,j-1);//不是就找下一个 fangzheng[i][j]=0;//复原,方便下一次 x[i][k]=false; y[j][k]=false; cube[MAP[i][j]][k]=false; } } } void dfs_2(int i,int j)//从左上向右下,差不多 { if(fangzheng[i][j]) { if(i==9 && j==9) { ans=max(ans,sum()); return; } else { if(j==9) dfs_2(i+1,1); else dfs_2(i,j+1); } } else { for(int k=1;k<=9;k++) if(!x[i][k] && !y[j][k] && !cube[MAP[i][j]][k]) { fangzheng[i][j]=k; x[i][k]=true; y[j][k]=true; cube[MAP[i][j]][k]=true; if(j+1>9) { if(i+1>9) { ans=max(ans,sum()); fangzheng[i][j]=0; x[i][k]=false; y[j][k]=false; cube[MAP[i][j]][k]=false; return; } else dfs_2(i+1,1); } else dfs_2(i,j+1); fangzheng[i][j]=0; x[i][k]=false; y[j][k]=false; cube[MAP[i][j]][k]=false; } } } int main() { for(int i=1; i<=9; i++) for(int j=1; j<=9; j++) { cin>>fangzheng[i][j]; ///输入 if(fangzheng[i][j])//如果是填好了的数,做好标记 { x[i][fangzheng[i][j]]=true; y[j][fangzheng[i][j]]=true; cube[MAP[i][j]][fangzheng[i][j]]=true; } if (i+j<10 && fangzheng[i][j]==0) t1++; //左上的空 if (i+j>10 && fangzheng[i][j]==0) t2++; //右上的空 } if(t1>=t2) dfs1(9,9); //空格少就去哪边 else dfs_2(1,1); if(ans==0) cout<<"-1"; //没有最优解,就是搜不出来,无解 else cout<<ans; return 0; }