2016蓝桥 剪邮票
来源:互联网 发布:人工智能对社会 编辑:程序博客网 时间:2024/05/18 17:25
讲述来自:http://blog.csdn.net/u014552756/article/details/50946197#comments感谢作者
剪邮票
如【图1.jpg】, 有12张连在一起的12生肖的邮票。
现在你要从中剪下5张来,要求必须是连着的。
(仅仅连接一个角不算相连)
比如,【图2.jpg】,【图3.jpg】中,粉红色所示部分就是合格的剪取。
请你计算,一共有多少种不同的剪取方法。
思路:先找到5个数的组合,然后从第一个数字开始遍历,经过上下左右操作检测5个数是否都被访问一遍,如果5个数都可以遍历到则种类+1。
在原图中向上为-4,向下为+4,向左为-1,向右为+1,但是遇到3 4 5 7 8这种4+1=5但是这种情况不符合,所以重构一下原图:
这样,向上为-5,向下为+5,向左为-1,向右为+1,避免了每行最后一个+1后等于下一行第一个的情况。
作者代码:
#include <iostream> using namespace std; int mp[12]= {1,2,3,4,6,7,8,9,11,12,13,14}; int aa[5],vis[5],sum=0; int b[4]= {-1,1,-5,+5}; void dfs(int n) { for(int i=0; i<4; i++) { int t=aa[n]+b[i]; if(t<1||t>14||t==5||t==10) continue; for(int j=0; j<5; j++) if(!vis[j]&&aa[j]==t) { vis[j]=1; dfs(j); } } } int main() { for(int a=0; a<12; a++) for(int b=a+1; b<12; b++) for(int c=b+1; c<12; c++) for(int d=c+1; d<12; d++) for(int e=d+1; e<12; e++) { aa[0]=mp[a]; aa[1]=mp[b]; aa[2]=mp[c]; aa[3]=mp[d]; aa[4]=mp[e]; for(int i=0; i<5; i++) vis[i]=0; vis[0]=1; dfs(0); int flag=1;; for(int i=0; i<5; i++) { if(vis[i]!=1) { flag=0; break; } } if(flag==0) continue; else sum++; } cout<<sum<<endl; return 0; }
作者思路非常好,尤其重构图部分,确实省了很多功夫,而且代码也讲得很清楚,在阅读了很多次终于体会到一二,在这里我贴一下自己的代码,对数组以及其中的变量名进行重命名,希望阅读起来更方便,再次感谢原文作者
MyCode:
#include<stdio.h>int all[12]={1,2,3,4,6,7,8,9,11,12,13,14};//全部数 int random[5];//存放随机寻找到的5个数int visit[5];//是否被访问到的标记 //每个随机取出来的数random[i]对应一个visit[i],表示该数有没有被遍历过 int tag[4]={1,-1,5,-5};//向右+1,向左-1,向下+5,向上-5 void dfs(int n) //n代表随机数的下标random[n],这样random[i]和visit[i]可以一一对应起来 {int i,j;int t; for(i=0;i<4;i++){t=random[n]-tag[i]; //看他的上下左右,减1就是左。加一就是右 if(t<1||t>14||t==5||t==10)continue;//如果这个数t超过了范围就继续找 for(j=0;j<5;j++)//厉害了,找到一个在合理范围的数t {if(random[j]==t&&!visit[j])//而且t还是在我们事先找的随机数中,并且还没有遍历到,完美 {visit[j]=1;//标记一下,这个数我们找过了,而且是符合条件的 dfs(j);//继续找下一个成员 }}}} int main(){int sum=0;//计数 int a,b,c,d,e; //代表all[]数组的下标int i;//临时变量 for(a=0;a<12;a++){for(b=a+1;b<12;b++){for(c=b+1;c<12;c++){for(d=c+1;d<12;d++){for(e=d+1;e<12;e++){random[0]=all[a];random[1]=all[b];random[2]=all[c];random[3]=all[d];random[4]=all[e];//随机找到了五个数 for(i=0;i<5;i++){visit[i]=0; //初始化,现在每一个数都未被遍历 }visit[0]=1; //从第一个数出发,这个random[0]这个数已经被遍历过了 visit[0]=1 dfs(0);//从第一个数出发,开始找,看看能不能把其余的 4个数random[1-4]都找到,进入函数dfs //找完了,不知道五个数是否都能遍历到,都能遍历到即visit[]数组的元素都是一,当然这种情况就可取 int flag=1;for(i=0;i<5;i++) //看每一个random是否都遍历到了,如果是,就sum++,不是就继续找下一批 5个随机数重复过程 {if(!visit[i]){flag=0;break;}}if(!flag)continue;//这情况不行 else{//这情况可以,sum++ sum++;}}}}}}printf("%d\n",sum);}
0 0
- 2016蓝桥 剪邮票
- 蓝桥 剪邮票
- 蓝桥2016省赛 剪邮票
- 蓝桥 剪邮票 (dfs+bfs)
- 蓝桥杯2016:剪邮票
- 蓝桥杯 2016 7 剪邮票
- 剪邮票(2016年蓝桥杯)
- 蓝桥杯 2016省赛 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 剪邮票
- 物联网应用之在线水质监测
- android自定义View&自定义ViewGroup(上)
- Android-color.xml 资源文件
- html输入框密码设置十个字符(JavaScript实现)
- MPMoviePlayerController指定在线视频的开始时间
- 2016蓝桥 剪邮票
- Android 6.0动态权限介绍与处理
- librtmp & rtmpdump开源项目github
- 字符判断
- ajax的异步加载和return的失效
- 算法提高 7-2求arccos值
- MFC找不到控件ID的原因
- 玲珑acm 倍增
- android混淆