今有7对数字:两个1,两个2,两个3,…两个7,把它们排成一行。
要求,两个1间有1个其它数字,两个2间有2个其它数字,以此类推,两个7之间有7个其它数字。如下就是一个符合要求的排列:
17126425374635
当然,如果把它倒过来,也是符合要求的。
请你找出另一种符合要求的排列法,并且这个排列法是以74开头的。
这道题的基本思想还是dfs,回溯
74XXXX4X7XXXX
首先我们将按照题目摆放好 7 和 4 ,7将存在与数列的 0 与 8 ,4 将存在于数列的 1 与 6,然后我们将从下标为2 的开始摆放数字 根据摆放的数字,我们将填充与之对应的数 假设当前填充位为 l 填充值为value ,则另一个被填充的数位为 l+value+1 在填充之前我们将判断该数值之前在其它的数组中是否出现过,若出现过我们将修正更改,继续判断,下面我贴上代码
#include<iostream>
using namespace std;
struct z
{
int data;
bool flag = false;
}b[14];//申请长度为14的单元
bool pd(int value)
{
for (int i = 0; i < 14; i++)
{
if (value == b[i].data)
return false;
}
return true;
}
void f(int l)//l表示位置参数
{
if (l > 13)
{
for (int i = 0; i<14; i++)
{
cout << b[i].data << " ";
}
cout << endl;
}
if (l <= 13)//位置不越界
{
if (b[l].flag == true)f(l + 1);//如果当前的位置被占据,则进行下一个
else
{
for (int value = 1; value <= 6; value++)
{
if (b[l + 1 + value].flag == true)continue;//后面的位置也能存放
if (pd(value) == true)
{
b[l].data = value, b[l].flag = true;
b[l + 1 + value].data = value, b[l + 1 + value].flag = true;
f(l + 1);
b[l].flag = false, b[l + 1 + value].flag = false;
b[l].data = 0;
b[l + 1 + value].data = 0;
}
}
}
}
else
return;
}
int main()
{
//初始化条件,将初始位置设置好参数
b[0].data = 7, b[0].flag = true;
b[1].data = 4, b[1].flag = true;
b[6].data = 4, b[6].flag = true;
b[8].data = 7, b[8].flag = true;
//运行过程
f(0);
//结果输出
return 0;
}
注意:输出的数组必须从dfs中输出,因为此时输出的才满足条件,如果在主函数输出,输出的就一定不满足,在dfs函数中如果有输出就一定必须有复位,因为我们采用的是dfs以及回溯