【每日蓝桥】32、一五年省赛Java组真题“垒骰子”

你好呀,我是灰小猿,一个超会写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;
	}

}

输出样例:

 

其中有不足或者改进的地方,还希望小伙伴留言提出,一起学习!

感兴趣的小伙伴可以关注专栏!

灰小猿陪你一起进步!

猜你喜欢

转载自blog.csdn.net/weixin_44985880/article/details/114944022