你好呀,我是灰小猿,一个超会写bug的程序猿!
欢迎大家关注我的专栏“每日蓝桥”,该专栏的主要作用是和大家分享近几年蓝桥杯省赛及决赛等真题,解析其中存在的算法思想、数据结构等内容,帮助大家学习到更多的知识和技术!
标题:饮料换购
赌圣atm晚年迷恋上了垒骰子,就是吧骰子一个垒在另一个上面,不能歪歪扭扭,要垒成方柱体。
经过长期观察,atm发现稳定骰子的奥秘,有些数字的面贴着会互相排斥;
我们先来规范一下骰子,1的对面是4,2的对面是5,3的对面是6.
假设有m组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来,
Atm想计算一下有多少种不同的可能的垒骰子的方式。
两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。
由于方案数可能过多,请输出模10^9+7的结果
不要小看了atm的骰子的数量哦
【输入格式】
第一行两个整数n和m
n表示骰子数目
扫描二维码关注公众号,回复: 12789540 查看本文章接下来m行,每行两个整数a b,表示a和b不能紧贴在一起
【输出格式】
一行一个数,表示答案模10^9+7的结果
【样例输入】
2 1
1 2
【样例输出】
544
【数据范围】
对于30%的数据:n<=5
对于60%的数据:n<=100
对于100%的数据:0<=.n<=10^9,m<=36
资源约定:
峰值内存消耗(含虚拟机)< 256M
CPU消耗 < 2000ms
请严格按要求输出,不要画蛇添足的打印类似“请您输入...”的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句,不要使用jdk1.6及以上的版本特性
注意:主类的名称必须是Main 否则按无效代码处理。
解题思路:
本题可以使用递归的思想来求解,对六个骰子的每一面进行深搜递归,算出每一个面上的可能性,之后将所有的可能性相加,得到最终答案
答案源码:
public class Year2015_Bt9 { static long MOD = 1000000007; static int n = 0; static int[][] rejectArr = new int[7][7]; static int[] upToDown = new int[7]; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); int m = scanner.nextInt(); init();//对面骰子数据初始化 for (int i = 0; i < m; i++) { int x = scanner.nextInt(); int y = scanner.nextInt(); rejectArr[x][y] = 1; rejectArr[y][x] = 1; } long ans = 0; for (int j = 1; j <= 6; j++) { ans = (ans+4*f(n-1, j))%MOD; } System.out.println(ans); } private static long f(int num,int top) { if (num==0) { return 4; } long ans=0; //枚举骰子上面的数字的值 for (int j = 1; j <= 6; j++) { //如果对应的两个面排斥 if (rejectArr[top][upToDown[j]]==1) continue; ans = (ans + f(num-1, j))%MOD; } return ans; } public static void init() { upToDown[1] = 4; upToDown[2] = 5; upToDown[3] = 6; upToDown[4] = 1; upToDown[5] = 2; upToDown[6] = 3; } }
输出样例: