2018蓝桥杯校选题目3 填数游戏

大耗子 2020年02月24日 245次浏览

填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)

一共有多少种可能的填数方案?

20181208213110263
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。

代码构成如下

头部代码

#include <stdio.h>
#define ROW 3   // 行数
#define COL 4   // 列数
int sum = 0;    // 可以成立的排列组合方案个数

循环遍历数组,当前位置的数字是否和其他存放位置的一样。

// 填入的数字是否存在相同数字
int isT(int arr[][COL], int row, int col)
{
    // 循环所有数组位置
    for (int i = 0; i < ROW; i++)
    {
	for (int j = 0; j < COL; j++)
	{
            // 判断是否是自身位置, 因为自身位置一定等于自身
	    if (row == i && col == j)
		continue;
            // 判断数字是否相同 相同则返回真
	    if (arr[i][j] == arr[row][col])
		return true;
	}
    }
    // 都不相同返回假
    return false;
}

判断该数字的相邻位置是否有连续数字,且当前数字是否重复出现。

// 填入的数字是否成立
int isReal(int arr[][COL], int row, int col)
{
    //循环相邻的位置
    for (int i = row - 1; i <= row + 1; i++)
    {
	for (int j = col - 1; j <= col + 1; j++) 
	{
            //过滤九宫格超出数组范围的部分
	    if (j >= 0 && j<COL && i >= 0 && i<ROW) 
	    {
                //判断是否相邻  且 是否含有重复数字
		if (   arr[i][j] == arr[row][col] + 1 
                    || arr[i][j] == arr[row][col] - 1 
                    || isT(arr,row,col) ) 
		{
		    return 0;
		}
	    }
	}
    }
    return 1;
}

递归函数

数字填充递归路径 , 相当于将二维数组看成一位数组,从最后一位开始变更数字,暴力破解的方式填充数字

20181210080800833

//递归的函数,用于暴力找出所有情况
void def(int arr[][COL], int row, int col, int num) //num为存放了多少个数字 相当于树的深度
{
    num++;  //当前数字个数
    if (row > 2 || row<0 || col>3 || col < 0)//防止超出数组范围
    {
	return;
    }
    for (int i = 0; i < 10; i++)
    {
        arr[row][col] = i;
        // print(arr); //想看每一步的递归过程,请解开此注释
        if (isReal(arr, row, col) && arr[row][col + 1] != -3)  //此处-3作为不可存放
	    def(arr, row, col + 1, num);  //往右递归
        if (isReal(arr, row, col) && arr[row + 1][0] != -3) 
	    def(arr, row + 1, 0, num);  //往下递归
        if (num == 10 && isReal(arr, row, col)) //已经存放10个数字,同时达到题目要求条件
        {
            // print(arr); //想看每一步成功填入的过程,请解开此注释
            sum++;
        }
    }
    arr[row][col] = -2; //待填入的方格用-2表示
}

主函数

void main()
{
    // 赋值为-3 代表着是方块不可写入数字
    int arr[ROW][COL] = { 0 }; 
    for (int i = 0; i < 3; i++) // -2为待填入放个数组
	for (int j = 0; j < 4; j++)
	    arr[i][j] = -2;
    arr[0][0] = -3;  //-3禁止填入的位置,相当于墙
    arr[ROW - 1][COL - 1] = -3;
    def(arr, 0, 1, 0);
    printf("排列方式为%d种 \n", sum);
}

用来测试结果是否为真的代码

void print(int arr[][COL])
{
	for (int i = 0; i < ROW; i++)
	{
		for (int j = 0; j < COL; j++)
		{
			printf("%2d  ", arr[i][j]);
		}
		printf("\n");
	}
	printf("\n");

}