https://www.luogu.org/problemnew/show/P1074
Obviously, it's dfs, and there's no pruning and memorization, but preprocessing is troublesome
I use three two-dimensional arrays to store the state: visx[x][i] represents whether row x is selected or not, visy[y][i] represents whether column y is selected or not, visg[g][i] represents whether the ninth house G is selected or not
When traversing, it is found that VISX [x] [i] = = 0 & & Visy [y] [i] = = 0 & & visg [g] [i] = = 0, indicating that I can go down dfs without being selected
As for the order of traversal, when we play Sudoku, we all know that we must start from the place with more known points
For example, the first line: 7 0 0 9 0 0 0 0 1 has 6 unknown locations
Line 9: 0 8 0 5 0 4 0 1 2 only 4 positions are unknown, so we must consider line 9 first
So just sort the rows and adjust the traversal order
However, sorting leads to a problem that we don't know the first row after sorting is the first row. To solve this problem, we can use a structure to store several unknown positions of each row:
typedef struct { int nums=0; //Number of unknown locations int x; //Row number }node;
Finally, we need to maintain a one-dimensional array to hold the modified traversal sequence (of course, two-dimensional can also be used)
At the end of last, the maximum value should be updated every time a group of Sudoku solutions are found
See the code:
#include<bits/stdc++.h> using namespace std; typedef struct { int nums=0; int x; }node; node e[15]; int m[15][15],anss,u,visx[15][15],visy[15][15],visg[15][15],q[100],pre,flag; int s[11][11]={0,0,0,0,0,0,0,0,0,0,0, //It's lazy to save the scores in each position and type directly 0,6,6,6,6,6,6,6,6,6,0, 0,6,7,7,7,7,7,7,7,6,0, 0,6,7,8,8,8,8,8,7,6,0, 0,6,7,8,9,9,9,8,7,6,0, 0,6,7,8,9,10,9,8,7,6,0, 0,6,7,8,9,9,9,8,7,6,0, 0,6,7,8,8,8,8,8,7,6,0, 0,6,7,7,7,7,7,7,7,6,0, 0,6,6,6,6,6,6,6,6,6,0, 0,0,0,0,0,0,0,0,0,0,0}; bool cmp(node a,node b) { return a.nums<b.nums; } void dfs(int t) { int i,j; if(t==u+1) { flag=1; int p=0; for(i=1;i<=9;i++) for(j=1;j<=9;j++) p+=m[i][j]*s[i][j]; anss=max(anss,p); //Update Max return; } int x=(q[t]-1)/9+1; int y=q[t]-(x-1)*9; int g=((x-1)/3)*3+(y-1)/3+1; for(i=1;i<=9;i++) { if(visx[x][i]==0&&visy[y][i]==0&&visg[g][i]==0) { visx[x][i]=1; visy[y][i]=1; visg[g][i]=1; m[x][y]=i; dfs(t+1); visx[x][i]=0; visy[y][i]=0; visg[g][i]=0; } } } int main() { int i,j; for(i=1;i<=9;i++) e[i].x=i; for(i=1;i<=9;i++) for(j=1;j<=9;j++) { scanf("%d",&m[i][j]); if(m[i][j]==0) e[i].nums++; else { pre+=m[i][j]*s[i][j]; visx[i][m[i][j]]=1; visy[j][m[i][j]]=1; int g=((i-1)/3)*3+(j-1)/3+1; //Calculate which nine palace grid the current point belongs to visg[g][m[i][j]]=1; } } sort(e+1,e+10,cmp); for(i=1;i<=9;i++) for(j=1;j<=9;j++) { if(m[e[i].x][j]==0) { int nums=(e[i].x-1)*9+j; //If the current position is unknown, put it in the sequence to be traversed q[++u]=nums; //u How many unknown points are recorded } } dfs(1); if(flag==0) //If there is no solution { cout<<-1<<endl; return 0; } cout<<anss<<endl; }