记录编号 243916 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOIP 2009]靶形数独 最终得分 100
用户昵称 GravatarRapiz 是否通过 通过
代码语言 C++ 运行时间 1.577 s
提交时间 2016-03-30 21:46:10 内存使用 0.31 MiB
显示代码纯文本
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<assert.h>
using std::max;
using std::cin;
using std::cout;
using std::endl;
const int MAXN=9+1,FULL=(1<<9)-1,getsc[][10]={
{0,0,0,0,0,0,0,0,0,0},
{0,6,6,6,6,6,6,6,6,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,9,10,9,8,7,6},
{0,6,7,8,9,9,9,8,7,6},
{0,6,7,8,8,8,8,8,7,6},
{0,6,7,7,7,7,7,7,7,6},
{0,6,6,6,6,6,6,6,6,6},
};
int r[MAXN],c[MAXN],map[MAXN][MAXN],b[13],ans=-1,l=81;
inline int xy2b(int x,int y){
	return (x+3-1)/3+(y+3-1)/3*3;
}
inline void set(int x,int y,int k){
	r[x]|=(1<<k),c[y]|=(1<<k),b[xy2b(x,y)]|=(1<<k),map[x][y]=k;
}
inline void take(int x,int y,int k){
	r[x]&=~(1<<k),c[y]&=~(1<<k),b[xy2b(x,y)]&=~(1<<k),map[x][y]=0;
}
bool getpos(int& x,int &y,int& poss){
	bool flag=0;
	int n=10,cnt,now,t;
	for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) if(map[i][j]==0){
		t=now=r[i]|c[j]|b[xy2b(i,j)],cnt=0;
		/*if(now==FULL) {
			cout<<"无解";
			continue;
		}*/
		while(now) now&=(now-1),cnt++;
		cnt=(9-cnt);
		if(cnt<n) x=i,y=j,n=cnt,flag=1,poss=t;
		if(cnt==1) break;
	}
	if(flag) return true;
	else return false;//false for 没有可填位置(无解或满) 
}
/*void show(int x=0,int y=0){
	cout<<endl;
	for(int i=1;i<=9;i++,cout<<endl) for(int j=1;j<=9;j++) cout<<((i==x&&j==y)?"|":"")<<map[i][j]<<' ';
	cout<<endl;
}
int worksc(){
	int res=0;
	for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) res+=map[i][j]*getsc[i][j];
	return res;
}*/
void dfs(int s,int left){//当前分数s,剩下空白left
	if(s+left*9*10<ans)
		return;
	int x,y,poss;
	if(!getpos(x,y,poss)&&left==0) {
		if(left!=0) return;
		ans=max(ans,s);
		//printf("get");
		//show();
	}
	else{
		for(int i=9;i>=1;i--) if(((poss>>i)&1)==0) {
			set(x,y,i);//show(x,y);
			dfs(s+i*getsc[x][y],left-1),take(x,y,i);
		}
	}
}
int main(){
	freopen("sudoku.in","r",stdin);
	freopen("sudoku.out","w",stdout);
	int t,now=0;
	for(int i=1;i<=9;i++) for(int j=1;j<=9;j++) {
		cin>>map[i][j];		
		if(map[i][j]) now+=map[i][j]*getsc[i][j],set(i,j,map[i][j]),l--;
	}
	dfs(now,l);
	/*for(int i=1;i<=9;i++,cout<<endl) for(int j=1;j<=9;j++) {
		int poss=r[i]&c[j]&b[xy2b(i,j)];
		for(int k=1;k<=9;k++) if((poss>>k)&1) cout<<k<<' ';
	}*/
	cout<<ans;
	//show();
}