1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
| sxb大神思路 #include<cstdio> #include<iostream> #include<cstring> using namespace std; int s=0; int n=0; int can[10][10];//记录能填多少数 int a[9][9]={ {6,6,6,6, 6,6,6,6,6} ,{6,7,7,7, 7,7,7,7,6} ,{6,7,8,8, 8,8,8,7,6} ,{6,7,8,9, 9,9,8,7,6} ,{6,7,8,9,10,9,8,7,6} ,{6,7,8,9, 9,9,8,7,6} ,{6,7,8,8, 8,8,8,7,6} ,{6,7,7,7, 7,7,7,7,6} ,{6,6,6,6, 6,6,6,6,6} };//打表 int c[9][9]={ 1,1,1,2,2,2,3,3,3, 1,1,1,2,2,2,3,3,3, 1,1,1,2,2,2,3,3,3, 4,4,4,5,5,5,6,6,6, 4,4,4,5,5,5,6,6,6, 4,4,4,5,5,5,6,6,6, 7,7,7,8,8,8,9,9,9, 7,7,7,8,8,8,9,9,9, 7,7,7,8,8,8,9,9,9, }; int b[99][99]; int f[10][10]; int fh[10][10]; int fs[10][10]; int max1=-1; int f1(int x,int y,int k) { if(!fh[x][k]&&!fs[y][k]&&!f[c[x][y]][k]) return 1; return 0; } void dfs(int X,int ans) { if(X>(81-n))//已填完 { max1=max(ans,max1); return; } memset(can,0,sizeof(can)); int x,y,mmin=99999999; for(int i=0;i<9;i++) for(int j=0;j<9;j++) if(!b[i][j]) { for(int k=1;k<=9;k++) if ( f1(i,j,k) ) can[i][j]++;
if(can[i][j]<mmin) { mmin=can[i][j]; x=i; y=j; }//找最小 if(mmin==1) break;//找到只能填一个的退出 } if(mmin==0)//无结果 return ; /*if(mmin==99999999)//已填完 ,应该没用 { max1=max(ans,max1); return; }*/ for(int i=1;i<=9;i++) { if(f1(x,y,i)) { b[x][y]=i; fh[x][i]=1; fs[y][i]=1; f[c[x][y]][i]=1; dfs(x+1,ans+a[x][y]*i); b[x][y]=0; fh[x][i]=0; fs[y][i]=0; f[c[x][y]][i]=0; } } } int main() { for(int i=0;i<=8;i++) for(int j=0;j<=8;j++) { scanf("%d",&b[i][j]); if(b[i][j]) { fh[i][b[i][j]]=1; fs[j][b[i][j]]=1; f[c[i][j]][b[i][j]]=1; s+=a[i][j]*b[i][j];//记录已填的价值 n++;//记录已填的数 } } dfs(1,s); printf("%d",max1); return 0; }
|