这个嘛。。
以前上课的时候写过一个解数独的程序,这个题顺顺利利的就过了。
我觉得我已经很暴力了。。。可是速度还是挺快的。
思路
还是枚举每个为0的点,计算这个点可能的数字数量,从最小的一个开始枚举着填。
#include <stdio.h>
#include <iostream>
#include <queue>
#include <algorithm>
#include <map>
#include <vector>
#include <cmath>
#include <string.h>
#include <stdlib.h>
#include <time.h>
using namespace std;
#define READ freopen("acm.in","r",stdin)
#define ll long long
#define PII pair<int,int>
#define PDI pair<double,int>
#define PDD pair<double,double>
#define MPI map<int,int>::iterator
#define fst first
#define sec second
#define MS(x,d) memset(x,d,sizeof(x))
#define INF 0x3f3f3f3f
#define ALL(x) x.begin(),x.end()
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define MAX 5500
#define ROOT 0,n-1,1
#define PB push_back
#define FOR(a,b,c) for(int a=b;a<c;a++)
int b[10][10];
bool flag;
int Cnt(int x,int y,bool used[])
{
MS(used,0);
for(int i=0;i<9;i++)
{
used[b[x][i]]=1;
used[b[i][y]]=1;
}
for(int i=(x/3)*3;i<(x/3)*3+3;i++)
for(int j=(y/3)*3;j<(y/3)*3+3;j++)
used[b[i][j]]=1;
int cnt=0;
for(int i=1;i<=9;i++)
if(!used[i])
cnt++;
return cnt;
}
int check(int &x,int &y,bool ret[])
{
int mi=100;
for(int i=0;i<9;i++)
for(int j=0;j<9;j++)
{
if(b[i][j]!=0)
continue;
bool used[11];
MS(used,0);
int res=Cnt(i,j,used);
if(res<mi)
{
mi=res;
x=i;
y=j;
for(int k=1;k<=9;k++)
ret[k]=used[k];
}
}
if(mi==100)
return 1;// 一个为0的都没了
if(mi==0)
return -1;// 有一个没办法排了
return 0;
}
void dfs()
{
int x,y;
bool used[11];
int res=check(x,y,used);
if(res==-1)
return ;
if(res==1)
{
flag=true;
return ;
}
for(int i=1;i<=9&&!flag;i++)
{
if(!used[i])
{
b[x][y]=i;
dfs();
if(flag)
return ;
b[x][y]=0;
}
}
}
int main()
{
// READ;
int n;
scanf("%d",&n);
while(n--)
{
flag=0;
for(int i=0;i<9;i++)
{
char num[10];
scanf("%s",num);
for(int j=0;j<9;j++)
b[i][j]=num[j]-'0';
}
dfs();
for(int i=0;i<9;i++)
{
for(int j=0;j<9;j++)
{
cout<<b[i][j];
}
cout<<endl;
}
}
return 0;
}