題目鏈接
1 暴力法(TLE)
#include<bits/stdc++.h>
using namespace std;
const int inf= 0x3f3f3f3f;
typedef long long ll;
int e[10][10];
int r[10][10]; //記錄該行 1-9是否出現 出現爲 1
int c[10][10];
int k[10][10][10];
struct node{
int x, y;
}cal[100];
int ck(int i,int j) //判斷i,j是否有滿足條件的答案
{
int tans;
vector<int>tmp;
for(int m=1;m<=9;m++)
{
if(r[i][m]==c[j][m]&&c[j][m]==k[(i-1)/3][(j-1)/3][m]
&&k[(i-1)/3][(j-1)/3][m]==0)
{
tmp.push_back(m);
}
}
if(tmp.size()==1) tans = tmp.back();
else tans = 0;
return tans;
}
void prin()
{
for(int i1=1;i1<=9;i1++)
{
for(int j1=1;j1<=9;j1++)
printf("%d ",e[i1][j1]);
printf("\n");
}
}
int main()
{
int cn=0,cnt=0;
for(int i=1;i<=9;i++) for(int j=1;j<=9;j++)
{
cin>>e[i][j];
r[i][e[i][j]]=1; //在這行 e[i][j]這個數出現了
c[j][e[i][j]]=1; //在這列 e[i][j]這個數出現了
k[(i-1)/3][(j-1)/3][e[i][j]]=1; //在這塊 出現了
if(e[i][j]==0)
{
cal[cn].x=i;
cal[cn].y=j;
cn++;
}
} //cn個需要處理的數
while(1)
{
for(int p=0;p<cn;p++)
{
int i = cal[p].x;
int j = cal[p].y;
if(e[i][j]) continue;
int tt = ck(i,j);
if(tt)
{
e[i][j] = tt;
r[i][tt]=c[j][tt]=k[(i-1)/3][(j-1)/3][tt]=1;
cnt++;
if(cnt==cn)
{
prin();
return 0;
}
}
}
}
}
2 回溯法
#include<bits/stdc++.h>
using namespace std;
const int inf= 0x3f3f3f3f;
typedef long long ll;
int e[10][10];
int r[10][10]; //記錄該行 1-9是否出現 出現爲 1
int c[10][10];
int k[3][3][10];
struct node{
int x, y;
}cal[100];
int cn;
int flag=0;
void dfs(int s)
{
if(flag) return ;
if(s==cn)
{
flag=1;
for(int i1=0;i1<9;i1++)
{
for(int j1=0;j1<9;j1++)
printf("%d ",e[i1][j1]);
printf("\n");
}
}
for(int m=1;m<=9;m++)
{
int i = cal[s].x;
int j = cal[s].y;
if(!r[i][m]&&!c[j][m]&&!k[i/3][j/3][m])
{
r[i][m] = c[j][m] = k[i/3][j/3][m]=1;
e[i][j] = m;
dfs(s+1);
r[i][m] = c[j][m] = k[i/3][j/3][m]=0;
e[i][j] = 0;
}
}
}
int main()
{
for(int i=0;i<9;i++) for(int j=0;j<9;j++)
{
cin>>e[i][j];
r[i][e[i][j]]=1; //在這行 e[i][j]這個數出現了
c[j][e[i][j]]=1; //在這列 e[i][j]這個數出現了
k[i/3][j/3][e[i][j]]=1; //在這塊 出現了
if(e[i][j]==0)
{
cal[cn].x=i;
cal[cn].y=j;
cn++;
}
}
dfs(0);
}