[第七届蓝桥杯省赛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;
}
 
                    
                
 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号