[第七届蓝桥杯省赛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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Freeman Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值