填入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");
}