思路:把3*3
的拉成1*9
的,读入的时候对非0的位置、用过的数字进行标记。
然后从第1个空开始填,填完之后去检查是否每行、每列、对角线的三个数之和是15。
是的话就记录下来,计数器自增。
剪枝:当计数器大于1时就不用再找了。
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 15;
int g[N], ans[N];
bool st[N], used[N]; //位置, 数字
int cnt;
void check()
{
int t[8] = {0};
t[0] = g[1] + g[2] + g[3];
t[1] = g[4] + g[5] + g[6];
t[2] = g[7] + g[8] + g[9];
t[3] = g[1] + g[4] + g[7];
t[4] = g[2] + g[5] + g[8];
t[5] = g[3] + g[6] + g[9];
t[6] = g[1] + g[5] + g[9];
t[7] = g[3] + g[5] + g[7];
for (int i = 0; i <= 7; i++) if (t[i] != 15) return;
cnt++;
for (int i = 1; i <= 9; i++) ans[i] = g[i];
}
void dfs(int x) // 第x个位置
{
if (cnt > 1) return;
if (x > 9)
{
check();
return;
}
if (st[x])
{
dfs(x + 1);
return;
}
for (int i = 1; i <= 9; i++)
{
if (!used[i])
{
g[x] = i;
used[i] = true;
dfs(x + 1);
used[i] = false;
}
}
}
int main()
{
for (int i = 1; i <= 9; i++)
{
cin >> g[i]; //数字
if (g[i])
{
st[i] = true;
used[g[i]] = true;
}
}
dfs(1);
if (cnt == 1)
{
for (int i = 1; i <= 9; i++)
{
cout << ans[i] << ' ';
if (i % 3 == 0) cout << endl;
}
}
else cout << "Too Many";
return 0;
}