蓝桥杯 方格填数 全排列函数(cf1)

题目:

如下的 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;
}
发布了7 篇原创文章 · 获赞 0 · 访问量 178

猜你喜欢

转载自blog.csdn.net/weixin_43790882/article/details/103973627