c语言一行黑白相间的瓷砖,磁砖样式——第八届蓝桥杯C语言B组(国赛)第二题...
原创
标题:磁砖样式
小明家的一面装饰墙原来是 3*10 的小方格。
现在手头有一批刚好能盖住2个小方格的长方形瓷砖。
瓷砖只有两种颜色:黄色和橙色。
小明想知道,对于这么简陋的原料,可以贴出多少种不同的花样来。
小明有个小小的强迫症:忍受不了任何2*2的小格子是同一种颜色。
(瓷砖不能切割,不能重叠,也不能只铺一部分。另外,只考虑组合图案,请忽略瓷砖的拼缝)
显然,对于 2*3 个小格子来说,口算都可以知道:一共10种贴法,如【p1.png所示】
但对于 3*10 的格子呢?肯定是个不小的数目,请你利用计算机的威力算出该数字。
注意:你需要提交的是一个整数,不要填写任何多余的内容(比如:说明性文字)
一开始的想法是在数组里面枚举出全部的情况组合,比如2*3的方格,用0/1代表两种颜色;
那么一共会有pow(2,6)=64种情况,然后用3个判断条件筛选出符合要求的贴砖方式:
1: 数码0/1有偶数个;
2:任意2*2的方格的数码不能相同;
3:任意一个方格在其相邻的(上/下/左/右)方格至少有一个相同的数码;
代码如下:
1 #include
2
3 int arr[3][6]={0};
4 int count=0;
5
6 int Judge(){
7 int i=0;
8 int j=0;
9 //条件1:偶数个0和1
10 int count_zero=0; //存储0/1个数
11 int count_one=0;
12 for(i=0;i<=2;i++){
13 for(j=0;j<=5;j++){
14 if(arr[i][j]==0){
15 count_zero++;
16 }
17 else{
18 count_one++;
19 }
20 }
21 }
22 if(count_zero%2!=0 || count_one%2!=0){
23 return 0;
24 }
25 //条件2:2*2方格的数字都不相同
26 int x=0;
27 int y=0;
28 for(x=0;x<=1;x++){ //循环至行数-1
29 for(y=0;y<=4;y++){ //循环至列数-1
30 int a=arr[x][y];
31 int b=arr[x][y+1];
32 int c=arr[x+1][y];
33 int d=arr[x+1][y+1];
34 if(a==b && a==c && a==d && b==c && b==d && c==d)
35 return 0;
36 }
37 }
38 //条件3:每个数的相邻位置要有与其相同的数
39 for(i=0;i<=2;i++){
40 for(j=0;j<=5;j++){
41 int value=arr[i][j];
42 if(i-1>=0){ //上
43 if(value==arr[i-1][j]){
44 continue;
45 }
46 }
47 if(i+1<=1){ //下
48 if(value==arr[i+1][j]){
49 continue;
50 }
51 }
52 if(j-1>=0){ //左
53 if(value==arr[i][j-1]){
54 continue;
55 }
56 }
57 if(j+1<=2){ //右
58 if(value==arr[i][j+1]){
59 continue;
60 }
61 else{ //没有相邻的数码
62 return 0;
63 }
64 }
65 }
66 }
67 return 1;
68 }
69
70 void Style(int i,int j){ //i行、j列
71
72 if(i==2 && j==6){ //得到一种贴砖方式
73
74 if(Judge()==1){
75 /*
76 int a=0; //输出
77 int b=0;
78 for(a=0;a<=1;a++){
79 for(b=0;b<=2;b++){
80 printf("%d ",arr[a][b]);
81 if(b==2){
82 printf("\n");
83 }
84 }
85 }
86 */
87 count++;
88 }
89 return;
90 }
91
92 if(j==6){
93 i++;
94 j=0;
95 }
96 int v=0;
97 for(v=0;v<=1;v++){ //每个位置0-1循环
98 arr[i][j]=v;
99 Style(i,j+1);
100 arr[i][j]=0; //回溯
101 }
102 }
103
104 int main(){
105 Style(0,0);
106 printf("%d",count);
107 return 0;
108 }
只检验了2*3、3*6的方格的样例,2*3的样例输出了正确的答案,3*6的输出错误。
3*10的数据量太大跑不出来了。
上面的3个控制条件太少,像
1 0 1 1 0 0
1 1 0 0 0 1
1 0 1 1 0 1
这样的贴砖方式能通过条件但却是不符合要求的,因为这种方式太过于暴力,所以没有继续改进。
此题应该通过DFS解决:
3*10的方格,每个空方格都可以有4种贴法:(我们以1/2号定义两种颜色的砖)
横着贴1号砖、横着贴2号砖、竖着贴1号砖、竖着贴2号砖
所以我们用DFS搜索每块空砖的这4种贴法即可。
1 #include
2 #define row 3
3 #define rank 10
4
5 int count=0;
6 int arr[row+2][rank+2]={0}; //--------------①
7
8 int Judge(int x,int y){ //每一块砖的左上、右上、左下、右下四个2*2方格
9 if(arr[x][y]==arr[x-1][y] && arr[x][y]==arr[x-1][y-1] && arr[x][y]==arr[x][y-1]){ //左上
10 return 0;
11 }
12 if(arr[x][y]==arr[x-1][y] && arr[x][y]==arr[x-1][y+1] && arr[x][y]==arr[x][y+1]){ //右上
13 return 0;
14 }
15 if(arr[x][y]==arr[x][y-1] && arr[x][y]==arr[x+1][y-1] && arr[x][y]==arr[x+1][y]){ //左下
16 return 0;
17 }
18 if(arr[x][y]==arr[x][y+1] && arr[x][y]==arr[x+1][y] && arr[x][y]==arr[x+1][y+1]){ //右下
19 return 0;
20 }
21 return 1;
22 }
23
24 void dfs(int x,int y){
25 if(x==3 && y==11){
26 count++;
27 return;
28 }
29 if(y==11){
30 dfs(x+1,1);
31 return;
32 }
33 if(arr[x][y]==-1){ //4种铺法可以任意顺序
34 if(arr[x][y+1]==-1){ // 横铺1
35 arr[x][y]=1;
36 arr[x][y+1]=1;
37 if(Judge(x,y)==1){
38 dfs(x,y+1);
39 }
40 arr[x][y]=-1;
41 arr[x][y+1]=-1;
42 }
43 if(arr[x+1][y]==-1){ // 竖铺2
44 arr[x][y]=2;
45 arr[x+1][y]=2;
46 if(Judge(x,y)==1){
47 dfs(x,y+1);
48 }
49 arr[x][y]=-1;
50 arr[x+1][y]=-1;
51 }
52 if(arr[x+1][y]==-1){ // 竖铺1
53 arr[x][y]=1;
54 arr[x+1][y]=1;
55 if(Judge(x,y)==1){
56 dfs(x,y+1);
57 }
58 arr[x][y]=-1;
59 arr[x+1][y]=-1;
60 }
61 if(arr[x][y+1]==-1){ // 横铺2
62 arr[x][y]=2;
63 arr[x][y+1]=2;
64 if(Judge(x,y)==1){
65 dfs(x,y+1);
66 }
67 arr[x][y]=-1;
68 arr[x][y+1]=-1;
69 }
70 }
71
72 else{
73 dfs(x,y+1);
74 }
75 }
76
77 int main(){
78 int i=0;
79 int j=0;
80 for(i=1;i<=3;i++){ //-------------②
81 for(j=1;j<=10;j++){
82 arr[i][j]=-1;
83 }
84 }
85 dfs(1,1);
86 printf("%d",count);
87 return 0;
88 }
对代码中①/②的解释:
①:申请5*12的空间为方便对3*10的方格进行2*2的判断
②:只能对3*10的方格进行赋值,保证第0/4行、第0/11列(即外围一圈)的值和里面3*10的方格不同,具有很大的便利性(请大家慢慢体会)。
答案:114434
3:38:00
2018-05-07
c语言一行黑白相间的瓷砖,磁砖样式——第八届蓝桥杯C语言B组(国赛)第二题...相关推荐
- 2017蓝桥杯C/C++B组国赛-瓷砖样式
题目 题目链接 题解 DFS. 方案需要满足的要求: 只能有黄和橙两种颜色: 必须填满: 任何一种颜色都不允许同时出现在 2 × 2 2×2 2×2 的方格中: 任意一种颜色图案都必须能由 2 × 1 ...
- c语言一行黑白相间的瓷砖,C语言编程练习15:贴瓷砖
题目描述 有一块大小是 2 * n 的墙面,现在需要用2种规格的瓷砖铺满,瓷砖规格分别是 2 * 1 和 2 * 2,请计算一共有多少种铺设的方法. 输入 输入的第一行包含一个正整数T(T<=2 ...
- c语言一行黑白相间的瓷砖,卫生间黑白色的瓷砖好看吗 4款卫生间黑白瓷砖铺贴搭配效果图...
卫生间黑白色的瓷砖好看吗 4款卫生间黑白瓷砖铺贴搭配效果图 素雅干净的卫生间设计展现在你眼前,散发着一种整洁自然的视觉冲击,黑白瓷砖铺贴地面,经典的色调组合,同时还有防滑的效果,很适合卫生间.方形的浴 ...
- 3a三次方h c语言表达式,希尔伯特曲线——第八届蓝桥杯C语言B组(国赛)第三题...
原创 标题:希尔伯特曲线 希尔伯特曲线是以下一系列分形曲线 Hn 的极限.我们可以把 Hn 看作一条覆盖 2^n × 2^n 方格矩阵的曲线,曲线上一共有 2^n × 2^n 个顶点(包括左下角起点和 ...
- 数组三元数c语言程序,递增三元数组——第九届蓝桥杯C语言B组(省赛)第六题...
原创 标题:递增三元组 给定三个整数数组 A = [A1, A2, ... AN], B = [B1, B2, ... BN], C = [C1, C2, ... CN], 请你统计有多少个三元组(i ...
- 第八届蓝桥杯决赛 磁砖样式
标题:磁砖样式 小明家的一面装饰墙原来是 3*10 的小方格. 现在手头有一批刚好能盖住2个小方格的长方形瓷砖. 瓷砖只有两种颜色:黄色和橙色. 小明想知道,对于这么简陋的原料,可以贴出多少种不同的花 ...
- 第八届蓝桥杯决赛 磁砖样式(枚举)
标题:磁砖样式 小明家的一面装饰墙原来是 3*10 的小方格. 现在手头有一批刚好能盖住2个小方格的长方形瓷砖. 瓷砖只有两种颜色:黄色和橙色. 小明想知道,对于这么简陋的原料,可以贴出多少种不同的花 ...
- 2017/National _C_C++_B/2/磁砖样式
标题:磁砖样式 小明家的一面装饰墙原来是 3*10 的小方格. 现在手头有一批刚好能盖住2个小方格的长方形瓷砖. 瓷砖只有两种颜色:黄色和橙色. 小明想知道,对于这么简陋的原料,可以贴出多少种不同的花 ...
- 蓝桥杯7届c语言 c组答案,第七届蓝桥杯C语言C组-(自己懂的题目)
第七届蓝桥杯C语言C组-(自己懂的题目) 表示刚刚查了成绩,省赛一等奖,有资格去北京了,然后写一下总结, 先来写一下我懂的题目,毕竟我也是菜鸟,听说国赛比预赛难几个等级... 第一题 报纸页数 X星球 ...
最新文章
- 宽带Internet连接的类型—Vecloud微云
- nginx https反向代理tomcat
- C# 使用反射设置某个对象的属性或读取某个对象的属性
- 微信 小程序组件 分享按钮
- java泛型程序设计——约束与局限性
- 执行 redis-dump 报错:Error connecting to Redis on localhost:6379 (Redis::TimeoutError)
- Item 13 Minimize the accessibility of classes and members
- 7.python实现高效端口扫描器之nmap模块
- 学习JDK源码(一):String
- 小猿圈python视频_小猿圈python学习-格式化打印
- CTC算法详解之训练篇
- JavaScript设计模式 - 适配器模式
- js实现oss批量下载文件_远程URL文件批量下载打包的方法
- Simon Knowles:30年做成三家独角兽公司,AI芯片创业的底层逻辑
- Hbase------regionServer
- pandas dataframe drop函数
- 面试官:说说left join和left semi join 两者有什么区别?
- IMU:姿态解算算法集合
- AD域实现统一用户管理
- 分享百度短网址生成工具和接口 mr.baidu.com/xxxxx