题解 DTOJ #1097. 填充棋盘 chessboard

欢迎访问 My Luogu Space

【题目大意】

有一个 n ∗ m n*m nm 的棋盘,每个格子里面都有 “N O I P” 四个字母当中的一个。

如果这个棋盘内每一个 2 ∗ 2 2*2 22 的田字格里都有这四个字母,那么我们称之为 “幸运棋盘”。

现在请求出有多少个不同的幸运棋盘(不考虑翻转)。


【题解】

对于最左上角的一个田字格,一共有 4 ∗ 3 ∗ 2 ∗ 1 = 24 4*3*2*1=24 4321=24 种填法。


如图是一种填法:
在这里插入图片描述
接下来我们考虑每一列能怎样进行变化。

从第三列开始,每一列都能向下(向上等效)移动一格:
在这里插入图片描述在这里插入图片描述
因此只考虑列,有 2 m − 2 2^{m-2} 2m2 种填法。

而对于每一行,同理也有 2 n − 2 2^{n-2} 2n2 种填法。

显然,这样的移动方法可以考虑到所有的情况。

我们发现,如果有一列进行了变动,那么其他的列不受影响,而所有的行都不能进行变动,而每一行进行变动也同理,符合加法计数原理。并且这样的计算方式会计算原本的填法两次,因此要减一。

最终 a n s = 24 ∗ ( 2 n − 2 + 2 m − 2 − 1 ) ans=24*(2^{n-2}+2^{m-2}-1) ans=24(2n2+2m21)


【代码】

// output format !!!
// long long !!!
#include <bits/stdc++.h>
typedef long long LL;
using namespace std;
const int MOD = 1e9+7;

int n, m;

LL fpow(LL a, int k){
	LL c=1;
	while(k){
		if(k&1) c = c*a%MOD;
		a = a*a%MOD, k >>= 1;
	}
	return c;
}
int main(){
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);
	scanf("%d%d", &n, &m);
	printf("%lld", 24*(fpow(2, m-2)+fpow(2, n-2)-1)%MOD);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值