小白打卡第一次自己做出来的的dfs!感动!
有些繁琐 欢迎大家有更好的办法留言优化。
题外话:每个人刚接触新的知识点都很难的,不要怀疑自己呀,只是每个人接触这个的时间不同所以掌握的程度也不同。每当我坚持不下去的时候都会看看周围的小伙伴,他们可以我也可以的,借些胆子继续走下去。别太在意结果,在过程中努力,收获耐心,逻辑能力,理性思考的能力和代码能力都是终身收益的!小白继续加油~量变会造成质变
题目链接
思路:
1.读入数据
2.dfs深度优先搜索
/*
b[][]用来存满足条件的情况 便于输出
st[]表示1-9数据是否使用过->满足题目每个数只能用一次的要求
维护两个数据
sum1->9个数中不为0的个数
x->记录当前位置(二维坐标不好变化就存一维的,在函数中转化为二维的))*/
依次访问二维数组坐标,判断是否为零,如果为零则表示这个位置需要填数,那么就放入未被访问过的数据,
最后当所有数填完后check1是否满足题目要求 ,每行每列和为15;
如果不是则原路返回,直到所有情况都走完。ans用来存满足条件的个数(如果是多个函数都需要用到的数据可以放在全局变量更方便)
代码
#include <iostream>
using namespace std;
int a[4][4];
int b[4][4];
int st[15], sum;
int ans;
bool check()
{
int q;
for (int j = 1; j < 4; j++)
{
q = 0;
for (int i = 1; i < 4; i++)
{
q += a[j][i];
}
if (q != 15)
return false;
}
for (int j = 1; j < 4; j++)
{
q = 0;
for (int i = 1; i < 4; i++)
{
q += a[i][j];
}
if (q != 15)
return false;
}
q = 0;
for (int j = 1; j < 4; j++)
{
q += a[j][j];
}
if (q != 15)
return false;
q = 0;
for (int j = 1; j < 4; j++)
{
q += a[j][4 - j];
}
if (q != 15)
return false;
else return true;
}
void dfs(int sum1, int x)
{
if (sum1 == 9)//满足条件的9个数为一种状态
{
if(ans>1)
return;
if (check())
{
ans++;
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++)
{
b[i][j]=a[i][j];
}}}
return;
}
int tx = x / 3 + 1;//转换为二维坐标
int ty = x % 3;
if (ty == 0)
{
ty = 3;
tx = tx - 1;
}
if (a[tx][ty] == 0)
{
for (int i = 1; i <= 9; i++)
{
if (!st[i])//还需要检查 是否满足条件 随便找一个数填进去
{
a[tx][ty] = i;
st[i] = 1;
sum++; x++;
dfs(sum,x);//如何遍历二维数组
a[tx][ty] = 0;
st[i] = 0;
sum--; x--;
}
}
}
else {
x++;
dfs(sum, x);
x--;
}
}
int main()
{
for (int i = 1; i <= 3; i++) {//读入 计数 表示状态
for (int j = 1; j <= 3; j++)
{
cin >> a[i][j];
if (a[i][j] != 0)
{
st[a[i][j]] = 1;
sum++;
}
}
}
dfs(sum, 1);
if (ans == 1)
{
for (int i = 1; i <= 3; i++) {
for (int j = 1; j <= 3; j++)
{
cout << b[i][j]<<" ";
}
cout<<"\n";
}
}
else
{
cout << "Too many";
}
return 0;
}
//优化!
看到题解里有其他方法
dfs1-9的全排列 看有多少个满足题意!
这种是从终点出发,对比起点。
这个题目是一个单一起点多终点的题目