蓝桥杯真题训练——第六届Java A组第九题

一、题目

赌圣atm晚年迷恋上了垒骰子,就是把骰子一个垒在另一个上边,不能歪歪扭扭,要垒成方柱体。经过长期观察,atm 发现了稳定骰子的奥秘:有些数字的面贴着会互相排斥!我们先来规范一下骰子:1 的对面是 4,2 的对面是 5,3 的对面是 6。假设有 m 组互斥现象,每组中的那两个数字的面紧贴在一起,骰子就不能稳定的垒起来。 atm想计算一下有多少种不同的可能的垒骰子方式。两种垒骰子方式相同,当且仅当这两种方式中对应高度的骰子的对应数字的朝向都相同。由于方案数可能过多,请输出模 10^9 + 7 的结果。不要小看了 atm 的骰子数量哦~

输入格式:
第一行两个整数 n,m。n表示骰子数目。接下来 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

二、递归法

1.知识点

(1) 以后只要看到出现说可能性为多少的,并且有类似于一层一层情况的,说明就是要试探每一种情况,而这种的都要想到直接用暴力递归确定可能性,即先确定第一层的情况,然后再递归寻找下一层的情况

就像这题,从上往下第一个骰子,朝上的数字有六种情况,注意要以上为准,这样才能确定下面的会不会冲突(不考虑旋转,如果考虑旋转的话,朝上数字的每一种情况都可以旋转四次,所以每一个情况都要乘以4),如果不考虑冲突的话,每一种情况对应的下一层也有六种情况,因此可以直接用递归寻找下一层,递归停止条件就是 层数为0,说明前面的n个骰子已经确定方向了

//第一层
for(int i=1;i<=6;i++){
  ans=ans+f(i,n-1);//下一层,第一个参数就是像下一层说明这一层是哪面朝下,第二个参数就是说明是那一层,这是不不考虑旋转的,如果考虑的话就是要ans=ans+f(i,n-1)
 }

//递归函数
f(int up,int cnt){
if(cnt==0) return 1;//不考虑旋转,说明前面的n层已经确定了一种摆放情况,如果可以旋转的话左右前后可以进行旋转四次,所以要return 4;
for(int i=1;i<=6;i++)//这一层朝上的情况
{
  if(confilct[op[up]][i]==true) continue;//冲突则跳过
  ans =ans+f(i,cnt-1);
}
return ans;
}

2.完整代码

import java.util.*;

public class _09垒骰子 {
	static int []op=new int[7];
	static boolean [][]confilct=new boolean[7][7];
	static int MOD=100000007;
	
	static void init() {
		for(int i=0;i<=6;i++) {
			for(int j=0;j<=6;j++) {
				confilct[i][j]=false;
			}
		}
		op[1]=4;op[2]=5;op[3]=6;
		op[4]=1;op[5]=2;op[6]=3;
	}
	static int f(int up,int cnt) {
		if(cnt==0) return 4;//因为说明前面已经确定了第n层的了,而第n层的骰子可以旋转4个方向
		int ans=0;
		for(int i=1;i<=6;i++) {
			if(confilct[op[up]][i]==true) continue;
			ans=(ans+f(i,cnt-1))%MOD;
		}
		return ans;
	}
	
	public static void main(String []args) {
		init();
		Scanner cin=new Scanner (System.in);
		int n=cin.nextInt();int m=cin.nextInt();
		for(int i=0;i<m;i++) {
			int a=cin.nextInt();
			int b=cin.nextInt();
			confilct[a][b]=true;
			confilct[b][a]=true;
		}
		int ans=0;
		for(int i=1;i<=6;i++) {
			ans=(ans+(4*f(i,n-1))%MOD)%MOD;//n-1层的方案数已确定,但是第1层可以每一个up可以旋转,所以每次都要乘于1个4
		}
		System.out.print(ans);
	}

}

三、矩阵快速幂法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值