1、问题描述
问题描述:
如下的10个格子
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
2、我对这个问题的看法
在我看来,首先要把这个图案转换为数组存储在内存中,从而把问题转化为对数组元素的全排列,并对排列好的情况进行判断,保证连续数字不相邻,再用一个计数因子统计数目即可。
注:通过相邻两个数字作差的绝对值是否为1,来判断他们是否为相邻数字。
绝对值函数:fabs( )
3、全排列的实现
算法原理:递归、回溯。
具体的算法原理在上篇博客介绍过了,这里就不赘述了。
https://blog.csdn.net/weixin_45620022/article/details/104985440
4、解法代码及结果
本题的答案为:1580
代码:
#include<iostream>
#include<cmath> //数学库函数头文件;
using namespace std;
int a[]={0,1,2,3,4,5,6,7,8,9}; //定义存放数字的数组;
int number=0; //计数因子;
bool check() //检查该情况是否符合题意;判断方法:该元素与其他相邻差的绝对值不等于1,保证两者不相邻;
{
if(fabs(a[0]-a[1])==1||fabs(a[0]-a[3])==1||
fabs(a[0]-a[4])==1||fabs(a[0]-a[5])==1||
fabs(a[1]-a[2])==1||fabs(a[1]-a[4])==1||
fabs(a[1]-a[5])==1||fabs(a[1]-a[6])==1||
fabs(a[2]-a[5])==1||fabs(a[2]-a[6])==1||
fabs(a[3]-a[4])==1||fabs(a[3]-a[7])==1||
fabs(a[3]-a[8])==1||
fabs(a[4]-a[5])==1||fabs(a[4]-a[7])==1||
fabs(a[4]-a[8])==1||fabs(a[4]-a[9])==1||
fabs(a[5]-a[6])==1||fabs(a[5]-a[8])==1||
fabs(a[5]-a[9])==1||
fabs(a[6]-a[9])==1||
fabs(a[7]-a[8])==1||
fabs(a[8]-a[9])==1)
return false; //只要上述条件满足一个,就说明有两数相邻,返回false;
return true; //否则返回true;
}
void count(int k) //实现0~~9的全排列,其中k为数组下标;
{
if(k==10) //当k增加到10时,说明全排列完成,进行判断;
{
if(check()) //进行判断;
{
number++;
}
}
for(int i=k;i<10;i++) //实现全排列:递归&回溯;
{
{
int t=a[i];
a[i]=a[k];
a[k]=t;
}
count(k+1); //递归;
{
int t=a[i]; //回溯;
a[i]=a[k];
a[k]=t;
}
}
}
int main()
{
count(0); //数组下标从0开始;
cout<<number;
return 0;
}
运行截图:
运行环境:DEV c++
至此,整个题目解答完毕!!!
结语:以上就是我对这个问题的理解、解法,可能存在着更好、更简洁的解法代码,希望大家提出来,我们一起讨论,交换看法,共同进步。若上述代码中存在问题,望大家指正,谢谢大家看到结尾。(∩^∩)
奋斗的2351