[第七届蓝桥杯省赛C++B组]方格填数

题目来源:第七届蓝桥杯省赛C++B组

算法标签:全排列

题目描述:

如下的10个格子

+--+--+--+

|  |  |  |
+--+--+--+--+
|  |  |  |  |
+--+--+--+--+
|  |  |  |
+--+--+--+

(如果显示有问题,也可以参看【图1.jpg】)
在这里插入图片描述

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

题目答案:

1580

题目思路:

题目是格子填入数,连续两个数字不能相邻。
那么换句话说,我们得到判断条件,一个格子与上下左右对角绝对差值==1则不符合条件
很明显这道题是全排列判断,每个格子尝试不同的数字,那么我们现在的问题转换为了一个格子怎么做判断。

我们先假设第一个位子
在这里插入图片描述
将周边的距离为1的位子全部标记。

则第二个位子的标记方式即为下图,不用判断与上一个的关系,因为位于上一个时,已经判断过了。
在这里插入图片描述
当我们往下移动一层时,则如下图,上一层的两个与当前位子相邻的位子前一个位子都在之前的过程中与当前的位子判断过了。
在这里插入图片描述
让我们下沉到最后一层,即为下图,上一层,当前层左边都判断过,下一层没有:
在这里插入图片描述
则我们很容易得出代码!

题目代码:

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace  std;

int a[10];
int ans;

bool check()
{
	if (abs(a[0] - a[1]) == 1 || abs(a[0] - a[3]) == 1 || abs(a[0] - a[4]) == 1 || abs(a[0] - a[5]) == 1)return false;
	if (abs(a[1] - a[2]) == 1 || abs(a[1] - a[4]) == 1 || abs(a[1] - a[5]) == 1 || abs(a[1] - a[6]) == 1)return false;
	if (abs(a[2] - a[5]) == 1 || abs(a[2] - a[6]) == 1)return false;
	if (abs(a[3] - a[4]) == 1 || abs(a[3] - a[7]) == 1 || abs(a[3] - a[8]) == 1)return false;
	if (abs(a[4] - a[5]) == 1 || abs(a[4] - a[7]) == 1 || abs(a[4] - a[8]) == 1 || abs(a[4] - a[9]) == 1)return false;
	if (abs(a[5] - a[6]) == 1 || abs(a[5] - a[8]) == 1 || abs(a[5] - a[9]) == 1)return false;
	if (abs(a[6] - a[9]) == 1)return false;
	if (abs(a[7] - a[8]) == 1 || abs(a[8] - a[9]) == 1)return false;
	return true;
}
int main()
{
	for (int i = 0; i <= 9; i++)a[i] = i;//初始化

	do
	{
		if (check())ans++;//如果符合条件则答案加1
	} while (next_permutation(a, a + 10));
	cout << ans;
	return 0;
}
发布了155 篇原创文章 · 获赞 18 · 访问量 3906

猜你喜欢

转载自blog.csdn.net/weixin_43910320/article/details/105160618