垒骰子---蓝桥杯---矩阵快速幂---C++

题目描述:

赌圣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

思路

一开始完全不知道矩阵快速幂有什么用,直到昨天吃了亏,果然,还是刷题刷的少啊,我的线代真是学了浪费= =。
通过邻接矩阵来保存第一个骰子到第n个骰子两个状态的连通性即可能性, 通过矩阵乘法来实现状态堆积。最后的矩阵的每个元素即为第n个骰子各个状态的可能性也是所有可能性的各个分支。
之所以要乘n个4是因为每个骰子都可以旋转,且面是固定的,所以只有4个可能,而不是全排列的6种。
建立tool数组的意义在于, 骰子的头部不能是前一个状态不具有连通性的那个状态的背面,这话说的有点绕。

实现代码

#include
#include
typedef long long LL;
using namespace std;

const LL mod = 1e9 + 7;
const int tool[] = { 0,4,5,6,1,2,3 }; //存取下标的对立面

struct Matrix {
	LL m[7][7];
	Matrix() { memset(m, 0, sizeof(m)); }
};
//普通快速幂
LL Qpow(LL num, LL n) {
	LL ans = 1;
	while (n) {
		if (n & 1) ans = ans * num % mod;
		n >>= 1;
		num = num * num % mod;
	}
	return ans;
}
//矩阵乘法
Matrix MarMul(Matrix a, Matrix b) {
	Matrix ans;
	for (int i = 1; i <= 6; i++) {
		for (int j = 1; j <= 6; j++) {
			for (int k = 1; k <= 6; k++) {
				ans.m[i][j] = (ans.m[i][j] + a.m[i][k] * b.m[k][j]) % mod;
			}
		}
	}
	return ans;
}
//矩阵快速幂
Matrix MarQpow(Matrix a, LL n) {
	Matrix ans;
	for (int i = 1; i <= 6; i++) ans.m[i][i] = 1;
	while (n > 0) {
		if (n & 1) ans = MarMul(ans, a);
		n >>= 1;
		a = MarMul(a, a);
	}
	return ans;
}

int main() {
	LL n, m, a, b, output = 0;
	Matrix ans;
	for (int i = 1; i <= 6; i++) {
		for (int j = 1; j <= 6; j++) ans.m[i][j] = 1;
	}
	cin >> n >> m;
	while (m--) {
		cin >> a >> b;
		ans.m[a][tool[b]] = ans.m[b][tool[a]] = 0;
	}
	ans = MarQpow(ans, n - 1);
	for (int i = 1; i <= 6; i++)
		for (int j = 1; j <= 6; j++) output = (output + ans.m[i][j]) % mod;
	cout << (output * Qpow(4, n)) % mod << endl;
	return 0;
}

你可能感兴趣的:(C++,蓝桥杯,矩阵快速幂,垒骰子,蓝桥杯,矩阵快速幂,C++,快速幂)