填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
我博客里面还有一个方格填数的,那是学长给我们的第一次测试的时候给我们出的题,跟这个一样的图,只是有所修改建议参考下(点这里!嘿嘿)
讲解: 格子里面放10个数,所以 可以用一个循环来给这个格子放数,那么什么时候放下一个数呢?当他满足了这个数只放了一次并且他的周围(8个方向)没有和他相邻的。
所以我们可以用一个标记数组来判重和一个函数判断他周围有没有相邻的。如果满足我们就继续放下一个数,直到10个格子填满了结束sum++;
然而判断是否能不能放这个数我们不需要检测他周围的8个方向,因为是从第一个数开始往后面放的,所以说明他后面的格子还没有放数就不需要去判断了。只用判断这个数的左边,左上,上面,上右的。
陷阱在我们的格子的初始化,我们会习惯性的设置为全局变量,所以初始化值就是0,但是我们不能放0,因为0也是格子里面能放的数之一。
正确答案:1580
#include<stdio.h>
#include<math.h>
int a[3][4]={-20};
int vis[10],sum;
int judge(int r,int c,int k)
{
if(c>0&&fabs(k-a[r][c-1])==1)return 0;
if(r>0&&c>0&&fabs(k-a[r-1][c-1])==1)return 0;
if(r>0&&fabs(k-a[r-1][c])==1)return 0;
if(r>0&&c<3&&fabs(k-a[r-1][c+1])==1)return 0;
return 1;
}
void dfs(int n)
{
if(n>=11)
{
sum++;
return ;
}
int r=n/4,c=n%4;
for(int i=0;i<10;i++)
{
if(!vis[i]&&judge(r,c,i))
{
a[r][c]=i;
vis[i]=1;
dfs(n+1);
vis[i]=0;
//a[r][c]=-20;
}
}
}
int main()
{
sum=0;
dfs(1);
printf("%d\n",sum);
return 0;
}
因为是蓝桥杯的题,大多人都用的是暴力搜索,(我所理解的暴力就是用全排列把所有情况都枚举一遍,然后再找出符合条件的)。快比赛了我就想着把我自己博客里的题过一遍,那时候还不知道这道题的原题是这样的,心里想着尽然看到了搜索,就试试把这道题做下试试,谁知道一敲代码就完蛋了,起初是只给格子里的数做了标记,忘了放数,最后答案比正确答案少了,想了好久我已经接邻崩溃了,晚上的课也逃了,就是不知道是哪里出的问题,最后突然看见别人给初始化为-很大的数(正的也行)我突然明白了,因为我的默认初始化是0,所以影响了放1的地方!!看见正确答案出来那刻瞬间心花怒放。(嘿嘿这会高兴,说的多了,一起加油啊!!)