蓝桥杯试题 剪邮票 C语言
2017-04-07 09:07
134 查看
剪邮票
如【图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但是这种情况不符合,需注意。
答案:116
如【图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但是这种情况不符合,需注意。
答案:116
#include <stdio.h> #include <stdbool.h> #include <stdlib.h> int record[100000][5] = {0}; int new_record[5] = {0}; int visit[13] = {0}; int count = 0; bool judge(int x)//判断是否相邻,相邻返回true { if(!x) return true; for(int i = x - 1; i >= 0; i--) { if(new_record[i] == 4 || new_record[i] == 5 || new_record[i] == 8 || new_record[i] == 9) { if(new_record[i] == 4) if( new_record[x] == 3 || new_record[x] == 8) return true; if(new_record[i] == 5) if(new_record[x] == 1 || new_record[x] == 6 || new_record[x] == 9) return true; if(new_record[i] == 8) if(new_record[x] == 4 || new_record[x] == 7 || new_record[x] == 12) return true; if(new_record[i] == 9) if(new_record[x] == 5 || new_record[x] == 10) return true; } else if( (abs(new_record[x] - new_record[i]) == 1) || (abs(new_record[x] - new_record[i]) == 4) )//相邻 return true; } return false; } bool judgeEnd(int count)//判断是否重复,不重复返回true { bool check1[100000] = {false}; for(int i = count - 1; i >= 0; i--) { bool check2[5] = {false}; for(int j = 0; j < 5; j++) { for(int k = 0; k < 5; k++) { if(record[i][j] == new_record[k])//重复 check2[j] = true; } } int flag = 0;//重复 for(int j = 0; j < 5; j++) { if(!check2[j])//不重复 { flag = 1;//不重复 check1[i] = true; } } if(!flag)//重复 return false; } for(int i = count - 1; i >= 0; i--) { if(!check1[i])//重复 return false; } //不重复 return true; } void fun(int x) { if(x == 5) { if(judgeEnd(count))//不重复 { for(int i = 0; i < 5; i++)//写入record record[count][i] = new_record[i]; count++; } return; } for(int i = 1; i <= 12; i++) { if(visit[i])//已访问 continue; new_record[x] = i; if( !judge(x) )//不相邻 continue; visit[i]++; fun(x + 1); visit[i]--; } } int main() { fun(0); printf("%d\n", count); for(int i = count - 1; i >= 0; i--)//打印结果,校验 { for(int j = 0; j < 5; j++) printf("%d ", record[i][j]); puts(""); } return 0; }
相关文章推荐
- 蓝桥杯第七届初赛试题 剪邮票
- 蓝桥杯 2011年第二届C语言初赛试题(1)
- 蓝桥杯 历届试题 K倍区间数(C语言)
- 蓝桥杯 历届试题 打印十字-----------------------C语言——菜鸟级
- 蓝桥杯 - 历届试题 分糖果 C语言实现
- 蓝桥杯 2011年第二届C语言初赛试题(4)
- 蓝桥杯 第七届省赛试题 剪邮票
- 蓝桥杯 历届试题 对局匹配(dp满分通过)---------C语言
- 蓝桥杯 2011年第二届C语言初赛试题(5)
- 蓝桥杯 邮票(动态规划)----------------------C语言——菜鸟级
- 蓝桥杯 历届试题 连续区间数----------------------C语言——菜鸟级
- 蓝桥杯 历届试题 剪邮票
- 第七届蓝桥杯【省赛试题7】剪邮票
- 蓝桥杯 2011年第二届C语言初赛试题(2)
- 第七届蓝桥杯B组试题(剪邮票)
- 蓝桥杯 - 算法训练 邮票 C语言实现
- 第七届蓝桥杯【省赛试题6】方格填数C语言代码
- 蓝桥杯 2011年第二届C语言初赛试题(2) 中奖计算
- 2014届第五届蓝桥杯 C语言本科B组试题
- 蓝桥杯 - 历届试题 兰顿蚂蚁 C语言实现