第十届蓝桥杯C语言校选难题

题目:填入0~9的数字。

要求:连续的两个数字不能相邻(左右、上下、对角都算相邻)一共有多少种可能的填数方案?

                                                            

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

代码构成如下

头部:
#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;

}
 

递归函数

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

                                                            


//递归的函数,用于暴力找出所有情况

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");

}
 

猜你喜欢

转载自blog.csdn.net/Dimo__/article/details/84935574