第七届蓝桥杯CC++B组省赛题目——方格填数
Posted 就是干不掉我
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第七届蓝桥杯CC++B组省赛题目——方格填数相关的知识,希望对你有一定的参考价值。
第一部分:题目
方格填数
如下的10个格子
+--+--+--+
| | | |
+--+--+--+--+
| | | | |
+--+--+--+--+
| | | |
+--+--+--+
(如果显示有问题,也可以参看下图)
填入0~9的数字。要求:连续的两个数字不能相邻。
(左右、上下、对角都算相邻)
一共有多少种可能的填数方案?
请填写表示方案数目的整数。
注意:你提交的应该是一个整数,不要填写任何多余的内容或说明性文字。
第二部分:思路
这个题目有点表述不明,不知道0~9 可不可以重复使用。现在看来是不能重复使用的。
我的做法是把表格当做3行4列的数组,去掉一头一尾。
步骤:填数字->判断是否满足要求:相邻位置数字不能相邻。
需要注意的地方:保证数字没有重复使用:借助数组take,存储使用的数字,当所要填写的数字不在数组中时才可以填入。填入后存进数组。
判断是否满足相邻位置数字不能相邻的要求。看代码注释。
答案是:1580
第三部分:代码
#include<stdio.h> #include<stdlib.h> int count=0; int take[10],index=0;//记录当前已经填入的数字,用于填数字前判断是否已经使用,避免重复使用 int is_legal(int s[3][4])//判断是否满足要求:相邻位置数字不能相邻,就是两数字的差大于1.就是为什么s[0][0]、s[2][3]置为-2; { //这里的判断方法有点死板。假设每个位置都有上下左右和对角,只需要判断这些位置 //是不是在数组中,在就进行比较,不在就说明没有。 for(int i=0;i<3;i++) { for(int j=0;j<4;j++) { if(j-1>=0) { if(abs(s[i][j]-s[i][j-1])==1) { return 0; } } if(j+1<4) { if(abs(s[i][j]-s[i][j+1])==1) { return 0; } } if(i+1<3) { if(abs(s[i][j]-s[i+1][j])==1) { return 0; } } if(j-1>=0&&i+1<3) { if(abs(s[i][j]-s[i+1][j-1])==1) { return 0; } } if(j+1<4&&i+1<3) { if(abs(s[i][j]-s[i+1][j+1])==1) { return 0; } } if(i-1>=0&&j+1<4) { if(abs(s[i][j]-s[i-1][j+1])==1) { return 0; } } if(i-1>=0) { if(abs(s[i][j]-s[i-1][j])==1) { return 0; } } if(j-1>=0&&i-1>=0) { if(abs(s[i][j]-s[i-1][j-1])==1) { return 0; } } } } return 1; } void fun(int s[3][4],int a,int b) { int i; if(a==2&&b==3)//表示当前已经填满了表格,需要进行判断看是否满足要求 { if(is_legal(s)) { count++; } } else//继续填写 { for(i=0;i<=9;i++) { int j; for(j=0;j<index;j++)//填写的数字必须是没有用过的 { if(i==take[j]) { break; } } if(j==index) { s[a][b]=i; take[index++]=i; if(b<3)//表示当前行还没填完 { fun(s,a,b+1); } else//当前行填完就从下一行开始 { if(a<2)//判断当前行是否是最后一行 { fun(s,a+1,0); } } index--;//在一次填满结束后,当前位置的数字换为其他可以填写的数字 //所以当前使用的数字需要出去。 } } } } int main() { int s[3][4]; s[0][0]=-2; s[2][3]=-2; //左上角和右下角没有,为了方便判断把数值设为-2(小于-1大于10均可) fun(s,0,1); printf("%d\n",count); return 0; }
以上是关于第七届蓝桥杯CC++B组省赛题目——方格填数的主要内容,如果未能解决你的问题,请参考以下文章
蓝桥杯第六届-牌型总数&&蓝桥杯第七届-凑算式&&蓝桥杯第七届-方格填数