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++;
return; //遞歸出口;
}
}
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