原创


标题:磁砖样式

小明家的一面装饰墙原来是 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:任意一个方格在其相邻的(上/下/左/右)方格至少有一个相同的数码;

代码如下:

 #include<stdio.h>

 int arr[][]={};
int count=; int Judge(){
int i=;
int j=;
//条件1:偶数个0和1
int count_zero=; //存储0/1个数
int count_one=;
for(i=;i<=;i++){
for(j=;j<=;j++){
if(arr[i][j]==){
count_zero++;
}
else{
count_one++;
}
}
}
if(count_zero%!= || count_one%!=){
return ;
}
//条件2:2*2方格的数字都不相同
int x=;
int y=;
for(x=;x<=;x++){ //循环至行数-1
for(y=;y<=;y++){ //循环至列数-1
int a=arr[x][y];
int b=arr[x][y+];
int c=arr[x+][y];
int d=arr[x+][y+];
if(a==b && a==c && a==d && b==c && b==d && c==d)
return ;
}
}
//条件3:每个数的相邻位置要有与其相同的数
for(i=;i<=;i++){
for(j=;j<=;j++){
int value=arr[i][j];
if(i->=){ //上
if(value==arr[i-][j]){
continue;
}
}
if(i+<=){ //下
if(value==arr[i+][j]){
continue;
}
}
if(j->=){ //左
if(value==arr[i][j-]){
continue;
}
}
if(j+<=){ //右
if(value==arr[i][j+]){
continue;
}
else{ //没有相邻的数码
return ;
}
}
}
}
return ;
} void Style(int i,int j){ //i行、j列 if(i== && j==){ //得到一种贴砖方式 if(Judge()==){
/*
int a=0; //输出
int b=0;
for(a=0;a<=1;a++){
for(b=0;b<=2;b++){
printf("%d ",arr[a][b]);
if(b==2){
printf("\n");
}
}
}
*/
count++;
}
return;
} if(j==){
i++;
j=;
}
int v=;
for(v=;v<=;v++){ //每个位置0-1循环
arr[i][j]=v;
Style(i,j+);
arr[i][j]=; //回溯
}
} int main(){
Style(,);
printf("%d",count);
return ;
}

只检验了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种贴法即可。

 #include<stdio.h>
#define row 3
#define rank 10 int count=;
int arr[row+][rank+]={}; //--------------① int Judge(int x,int y){ //每一块砖的左上、右上、左下、右下四个2*2方格
if(arr[x][y]==arr[x-][y] && arr[x][y]==arr[x-][y-] && arr[x][y]==arr[x][y-]){ //左上
return ;
}
if(arr[x][y]==arr[x-][y] && arr[x][y]==arr[x-][y+] && arr[x][y]==arr[x][y+]){ //右上
return ;
}
if(arr[x][y]==arr[x][y-] && arr[x][y]==arr[x+][y-] && arr[x][y]==arr[x+][y]){ //左下
return ;
}
if(arr[x][y]==arr[x][y+] && arr[x][y]==arr[x+][y] && arr[x][y]==arr[x+][y+]){ //右下
return ;
}
return ;
} void dfs(int x,int y){
if(x== && y==){
count++;
return;
}
if(y==){
dfs(x+,);
return;
}
if(arr[x][y]==-){ //4种铺法可以任意顺序
if(arr[x][y+]==-){ // 横铺1
arr[x][y]=;
arr[x][y+]=;
if(Judge(x,y)==){
dfs(x,y+);
}
arr[x][y]=-;
arr[x][y+]=-;
}
if(arr[x+][y]==-){ // 竖铺2
arr[x][y]=;
arr[x+][y]=;
if(Judge(x,y)==){
dfs(x,y+);
}
arr[x][y]=-;
arr[x+][y]=-;
}
if(arr[x+][y]==-){ // 竖铺1
arr[x][y]=;
arr[x+][y]=;
if(Judge(x,y)==){
dfs(x,y+);
}
arr[x][y]=-;
arr[x+][y]=-;
}
if(arr[x][y+]==-){ // 横铺2
arr[x][y]=;
arr[x][y+]=;
if(Judge(x,y)==){
dfs(x,y+);
}
arr[x][y]=-;
arr[x][y+]=-;
}
} else{
dfs(x,y+);
}
} int main(){
int i=;
int j=;
for(i=;i<=;i++){ //-------------②
for(j=;j<=;j++){
arr[i][j]=-;
}
}
dfs(,);
printf("%d",count);
return ;
}

对代码中①/②的解释:

①:申请5*12的空间为方便对3*10的方格进行2*2的判断

②:只能对3*10的方格进行赋值,保证第0/4行、第0/11列(即外围一圈)的值和里面3*10的方格不同,具有很大的便利性(请大家慢慢体会)。

答案:114434

3:38:00

2018-05-07

磁砖样式——第八届蓝桥杯C语言B组(国赛)第二题的更多相关文章

  1. 2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告

    2016 第七届蓝桥杯 c/c++ B组省赛真题及解题报告 勘误1:第6题第4个 if最后一个条件粗心写错了,答案应为1580. 条件应为abs(a[3]-a[7])!=1,宝宝心理苦啊.!感谢zzh ...

  2. 发现环——第八届蓝桥杯C语言B组(国赛)第四题

    原创 标题:发现环 小明的实验室有N台电脑,编号1~N.原本这N台电脑之间有N-1条数据链接相连,恰好构成一个树形网络.在树形网络上,任意两台 电脑之间有唯一的路径相连. 不过在最近一次维护网络时,管 ...

  3. 希尔伯特曲线——第八届蓝桥杯C语言B组(国赛)第三题

    原创 标题:希尔伯特曲线 希尔伯特曲线是以下一系列分形曲线 Hn 的极限.我们可以把 Hn 看作一条覆盖 2^n × 2^n 方格矩阵的曲线,曲线上一共有 2^n × 2^n 个顶点(包括左下角起点和 ...

  4. 2017第八届蓝桥杯C/C++ B组省赛-日期问题

    标题:日期问题 小明正在整理一批历史文献.这些历史文献中出现了很多日期.小明知道这些日期都在1960年1月1日至2059年12月31日.令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的 ...

  5. 2017年第八届蓝桥杯C/C++B组省赛题目解析

    一. 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折优 ...

  6. 2017第八届蓝桥杯C/C++ B组省赛-购物单

    标题: 购物单 小明刚刚找到工作,老板人很好,只是老板夫人很爱购物.老板忙的时候经常让小明帮忙到商场代为购物.小明很厌烦,但又不好推辞. 这不,XX大促销又来了!老板夫人开出了长长的购物单,都是有打折 ...

  7. 2017第八届蓝桥杯C/C++ B组省赛-等差素数列

    标题:等差素数列 2,3,5,7,11,13,....是素数序列. 类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列. 上边的数列公差为30,长度为6. 200 ...

  8. 第八届蓝桥杯C/C++ B组省赛----分巧克力

    分巧克力 问题描述 儿童节那天有K位小朋友到小明家做客.小明拿出了珍藏的巧克力招待小朋友们. 小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形. 为了公平起见,小明需要从这 N 块巧 ...

  9. 【蓝桥杯】2018年第九届蓝桥杯C/C++B组省赛——B题 等差素数列

    题目 标题:等差素数列 2,3,5,7,11,13,....是素数序列. 类似:7,37,67,97,127,157 这样完全由素数组成的等差数列,叫等差素数数列. 上边的数列公差为30,长度为6. ...

随机推荐

  1. [翻译] HTKDynamicResizingCell

    HTKDynamicResizingCell https://github.com/henrytkirk/HTKDynamicResizingCell Subclassed UITableView/U ...

  2. C#中Array、ArrayList和List三者的区别

    1.Array  在C#中最早出现的.在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单. 它的空间大小是固定的,空间不够时也不能再次申请,所以需要事前确定合适的空间大小. 2. ...

  3. Linux中脚本的使用方法

    Linux中脚本的使用方法 一.前言 关于Linux中的脚本的用法,一直没有时间去好好地总结,正好今天下雨,就好好的整理一下思路吧,其实精通了一门语言,比如C语言,学习其他语言需要的成本是非常少的,同 ...

  4. matlab 黑白格子

    有一个生成黑白格子的函数 40 这个参数是改变大小的 img=checkerboard(40)<0.5; figure; imshow(img,[])

  5. php给图片加文字

    在图片上加文字是论坛,博客,新闻网站上最喜欢用的功能,防止盗图.这里看看代码是如何实现的. 首先还是upload_image.php这个文件,注意这里的caption文本框中输入的内容最终会写到图片上 ...

  6. ZT自老罗的博客 Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 分类: Android 2011-09-23 00:59 31568人阅读 评论(42) 收藏 举报 androidclass ...

  7. 怎么在Linux环境下通过VS Code调试Python 3+?

    今天突然想写一写Python了,于是就开始弄.使用源码包安装好Python3.6.6之后,发现Linux下只能通过python3来调用python 3.6.6.如果直接使用python的话,调用的是系 ...

  8. 利用TLE数据确定卫星轨道(1)-卫星轨道和TLE

    1.卫星轨道 太空中卫星和天体在各种引力的作用下都在一定的轨道中周期转动着,但实际的轨道是很复杂的,一般的项目也达不到那么精确的需求(其实精确的卫星参数数据也不可能随便公开的),所以采用一阶近似的开普 ...

  9. urllib下使用Xpath表达式示例

    urllib下使用Xpath表达式示例 使用xpath表达式需要先将需要匹配的数据转换成tree格式,这就需要先装lxml模块.安装方法可以使用pip安装. 示例代码: import urllib.r ...

  10. 35、springboot-运行状态监控使用Actuator

    Spring Boot Actuator 提供了运行状态监控的功能 Actuator 监控数据可以通过阻REST远程 shell 和JMX方式获得.我 首先来介绍通过 REST 方式查看 Actuat ...