比赛 练习赛 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 靶形数独 最终得分 100
用户昵称 梦那边的美好ET 运行时间 1.337 s
代码语言 C++ 内存使用 13.67 MiB
提交时间 2019-05-22 11:52:00
显示代码纯文本
#include<bits/stdc++.h>
typedef unsigned long long ull;
using namespace std;
const int maxn=20;
const int fs=(1<<9)-1;
int row[maxn],col[maxn],grid[maxn],state[maxn],st[maxn],a[maxn][maxn],pos[maxn][maxn],g[maxn],val[maxn][maxn];
int ans,ans2,sum,tot=45*9;
bool ok=0;
int Log2[(1<<9)+100];
void Swap(int &x,int &y){
	x^=y^=x^=y;
}
void Add(int x,int y,int p,int w){
	row[x]|=(1<<(w-1));
	col[y]|=(1<<(w-1));
	grid[p]|=(1<<(w-1));
}
void Del(int x,int y,int p,int w){
	row[x]^=(1<<(w-1));
	col[y]^=(1<<(w-1));
	grid[p]^=(1<<(w-1));
}
int Place(int x,int y){
	int cnt=0;
	for(int i=1;i<=7;i+=3){
		for(int j=1;j<=7;j+=3){
			cnt++;
			if(x>=i&&x<=i+2&&y>=j&&y<=j+2)return cnt;	
		}	
	}
}
void dfs(int rr,int no,int nosum){
	if(nosum*9+no<=ans)return;
	if(rr==10){
		ok=1;ans=max(ans,no);return;	
	}
	int r=st[rr],c=0,sr,sc,tmp,p,ss;
	sr=fs^state[r];
	if(!sr){dfs(rr+1,no,nosum);return;}
	sc=sr&(-sr);c=Log2[sc]+1;
	state[r]|=(1<<(c-1));
	ss=fs^(row[r]|col[c]|grid[pos[r][c]]);
	while(ss){
		tmp=ss&(-ss);ss-=tmp;
		p=Log2[tmp]+1;a[r][c]=p;
		Add(r,c,pos[r][c],p);
		if(sr==sc)dfs(rr+1,no+val[r][c]*p,nosum-p);
		else dfs(rr,no+val[r][c]*p,nosum-p);
		a[r][c]=0;Del(r,c,pos[r][c],p);
	}
	state[r]^=(1<<(c-1));
}
int main(){
	freopen("sudoku.in","r",stdin);
	freopen("sudoku.out","w",stdout);
	for(int i=0;i<=9;i++)Log2[1<<i]=i;
	for(int i=1;i<=9;i++){
		for(int j=1;j<=9;j++){
			scanf("%d",&a[i][j]);
			pos[i][j]=Place(i,j);
			if(!a[i][j])continue;
			Add(i,j,pos[i][j],a[i][j]);
			state[i]|=(1<<(j-1));
		}
	}
	for(int k=0;k<5;k++)
		for(int i=5-k;i<=5+k;i++){
			for(int j=5-k;j<=5+k;j++){
				if(i!=5-k&&j!=5-k&&i!=5+k&&j!=5+k)continue;
				val[i][j]=10-k;
				sum+=a[i][j];ans2+=val[i][j]*a[i][j];	
			}	
		}
	for(int i=1;i<=9;i++){
		st[i]=i;
		for(int j=1;j<=9;j++){
			if(a[i][j])continue;
			int tmp=0,cnt=0,ss=0;
			int s=fs^(row[i]|col[j]|grid[pos[i][j]]);
			while(s){
				tmp=s&(-s);s-=tmp;
				ss=Log2[tmp];cnt++;
				
			}if(cnt==1){
					a[i][j]=ss+1;
					Add(i,j,pos[i][j],a[i][j]);
					state[i]|=(1<<(j-1));
					sum+=a[i][j];ans2+=val[i][j]*a[i][j];	
				}
				else g[i]++;
		}
	}
	for(int i=1;i<=9;i++)
		for(int j=i+1;j<=9;j++)
			if(g[st[i]]>g[st[j]])swap(st[i],st[j]);
	dfs(1,0,tot-sum);
	if(!ok)printf("-1");
	else printf("%d",ans+ans2);
}