搜索,据说反着输入有奇效,要用位运算,然后剪不剪枝无所谓,没提速。
#include<iostream> #include<cstdio> using namespace std; int ans,tot,sum,sum1; bool flag; int board[10][10],val[10][10],squre[6][6]; int row[10],col[10]; inline int Max(int x,int y) { return x>y?x:y; } inline int calc() { int ret=0; for(int i=0;i<9;i++) { for(int j=0;j<9;j++) ret+=val[i][j]*board[i][j]; } return ret; } void dfs(int x,int y) { if(tot+sum*9*9+sum1<ans) return; // cout<<x<<" "<<y<<endl; if(x==8&&y==9) { flag=true; ans=Max(ans,tot+sum1); // cout<<"a"<<endl; return; } if(y==9) { dfs(x+1,0); return; } if(board[x][y]) { dfs(x,y+1); return; } for(int i=1;i<=9;i++) { if(!(row[x]&(1<<i))&&!(col[y]&(1<<i))&&!(squre[x/3][y/3]&(1<<i))) { board[x][y]=i; sum--; squre[x/3][y/3]^=(1<<i); row[x]^=(1<<i); col[y]^=(1<<i); tot+=val[x][y]*i; dfs(x,y+1); sum++; squre[x/3][y/3]^=(1<<i); row[x]^=(1<<i); col[y]^=(1<<i); tot-=val[x][y]*i; board[x][y]=0; } } } int main() { for(int i=0;i<9;i++) { val[0][i]=val[i][0]=val[8][i]=val[i][8]=6; } for(int i=1;i<8;i++) { val[1][i]=val[i][1]=val[7][i]=val[i][7]=7; } for(int i=2;i<7;i++) { val[2][i]=val[i][2]=val[6][i]=val[i][6]=8; } for(int i=3;i<6;i++) { val[3][i]=val[i][3]=val[5][i]=val[i][5]=9; } val[4][4]=10; for(int i=0;i<9;i++) { for(int j=0;j<9;j++) { scanf("%d",&board[i][j]); sum+=board[i][j]==0; sum1+=board[i][j]*val[i][j]; row[i]^=(1<<board[i][j]); col[j]^=(1<<board[i][j]); squre[i/3][j/3]^=(1<<board[i][j]); } } ans=sum1; dfs(0,0); if(!flag) cout<<-1<<endl; else cout<<ans<<endl; return 0; }