#include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N(9); int W[N][N]={ {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 B[N][N]={ {0,0,0,1,1,1,2,2,2}, {0,0,0,1,1,1,2,2,2}, {0,0,0,1,1,1,2,2,2}, {3,3,3,4,4,4,5,5,5}, {3,3,3,4,4,4,5,5,5}, {3,3,3,4,4,4,5,5,5}, {6,6,6,7,7,7,8,8,8}, {6,6,6,7,7,7,8,8,8}, {6,6,6,7,7,7,8,8,8}, }; unsigned int row[N]={0},col[N]={0},blk[N]={0},pos[257]={0}; int ans=-1; struct Sudoku{ struct node{ short x,y,opt; inline node():x(0),y(0),opt(0) {} }; short Su[N][N]; int blank; inline Sudoku(){ memset(Su,0,sizeof(Su)); blank=81; } inline void init(){ for(int i=0;i<9;i++) for(int j=0;j<9;j++) { scanf("%d",&(Su[i][j])); int num=Su[i][j]; if(Su[i][j]) set(i,j,num-1); } } inline void set(const int &x,const int &y,const int &k){ Su[x][y]=k+1;blank--; row[x]&=~(1<<k);col[y]&=~(1<<k);blk[B[x][y]]&=~(1<<k); } inline void un_set(const int &x,const int &y,const int &k){ Su[x][y]=0;blank++; row[x]|=(1<<k);col[y]|=(1<<k);blk[B[x][y]]|=(1<<k); } inline void cal(){ int sum=0; for(int i=0;i<N;i++) for(int j=0;j<N;j++) sum+=Su[i][j]*W[i][j]; ans=ans>sum?ans:sum; } inline node get_min(){ int min=81,opt; node P; for(int i=0;i<9;i++) for(int j=0;j<9;j++) if(!Su[i][j]) { opt=count(row[i]&col[j]&blk[B[i][j]]); if(opt<min) { min=opt; P.x=i,P.y=j,P.opt=min; if(!min) return P; } } return P; } inline int count(unsigned int x) { x=(x&0x55555555)+(x>>1&0x55555555); x=(x&0x33333333)+(x>>2&0x33333333); x=(x&0x0F0F0F0F)+(x>>4&0x0F0F0F0F); x=(x&0x00FF00FF)+(x>>8&0x00FF00FF); x=(x&0x0000FFFF)+(x>>16&0x0000FFFF); return x; } inline bool valid(const int &x,const int &y,const int &k){ return (row[x]&col[y]&blk[B[x][y]])>>k&1; } }Sudo; inline void init() { for(int i=0;i<N;i++) row[0]+=(1<<i); for(int i=0;i<N;i++) row[i]=col[i]=blk[i]=row[0]; for(int i=0;i<N;i++) pos[1<<i]=i; Sudo.init(); } void dfs(Sudoku &Sudo) { if(!Sudo.blank){ Sudo.cal(); return; } Sudoku::node P=Sudo.get_min(); if(!P.opt) return; int x=P.x,y=P.y; unsigned int k=row[x]&col[y]&blk[B[x][y]],p; while(k) { p=k&(~k+1); k-=p; Sudo.set(x,y,pos[p]); dfs(Sudo); Sudo.un_set(x,y,pos[p]); } } int main() { init(); dfs(Sudo); printf("%d\n",ans); return 0; } /************************************************************** Problem: 2291 User: admin Language: C++ Result: Accepted Time:811 ms Memory:1148 kb ****************************************************************/