比赛 |
练习赛 |
评测结果 |
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);
}