题目:
如下的 10 个格子
填入 [0,9]的数字。
要求:连续的两个数字不能相邻。(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
Input
无输入。
Output
输出一个整数,代表一共有多少种可能的填数方案。
思路:
一开始考虑深搜递归,发现递归真的是我的弱点,想了很久也没敲出来,只能用简单方法了。
首先引入一个知识点:
全排列next_permutation()函数的用法:
在头文件<algorithm>里面有如下代码:
int a[];
do
{
}
while(next_permutation(a,a+n));
可以产生a[0]~a[n-1]全排列。
判断的关键是:一个数与它周围八个方向数差的绝对值不能为1,暴力判断。
//#pragma GCC optimize(2)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
int m[5][6];
int judge(int i,int j)//判断8个方向
{
if(abs(m[i-1][j]-m[i][j])==1)
return 0;
if(abs(m[i+1][j]-m[i][j])==1)
return 0;
if(abs(m[i][j+1]-m[i][j])==1)
return 0;
if(abs(m[i][j-1]-m[i][j])==1)
return 0;
if(abs(m[i-1][j-1]-m[i][j])==1)
return 0;
if(abs(m[i+1][j-1]-m[i][j])==1)
return 0;
if(abs(m[i-1][j+1]-m[i][j])==1)
return 0;
if(abs(m[i+1][j+1]-m[i][j])==1)
return 0;
return 1;
}
int f()
{
if(judge(1,2)&&judge(1,3)&&judge(1,4)&&judge(2,1)&&judge(2,2)&&judge(2,3)&&judge(2,4)&&judge(3,1)&&judge(3,2)&&judge(3,3))
return 1;
return 0;
}
int main()
{
int ans=0;
int a[10]={2,3,4,5,6,7,8,9,10,11};
do{
m[1][2]=a[0];m[1][3]=a[1];m[1][4]=a[2];
m[2][1]=a[3];m[2][2]=a[4];m[2][3]=a[5];m[2][4]=a[6];
m[3][1]=a[7];m[3][2]=a[8];m[3][3]=a[9];
ans+=f();
}while(next_permutation(a,a+10));
cout<<ans<<endl;
return 0;
}