【NOIP2012模拟10.6】填充棋盘

206 篇文章 0 订阅
64 篇文章 0 订阅

Description
横一划竖一划,横一划竖一划…………小R画出了一个n*m的棋盘。

由于NOIP快要到了,小R有了一个奇妙的想法。

在棋盘的每一个小方格中填入N,O,I,P这4个字母中的一个,若棋盘中每一个2*2的小棋盘中都有N,O,I,P这4个字母,小R就认为这个棋盘是幸运棋盘。小R想知道一共有多少种不同的幸运棋盘。由于这个结果可能会很大,你只需输出对1,000,000,007取模后的值。

Input
两个整数n,m表示棋盘的大小。

Output
一个整数表示幸运棋盘的个数对1,000,000,007取模后的值。

Sample Input
2 3

Sample Output
48

Data Constraint

Hint
对于30%的数据,n,m≤10
对于70%的数据,n,m≤1,000,000
对于100%的数据,2≤n,m≤2,000,000,000

.
.
.
.
.
.
分析
22的方格中有24种不同的方案(具体可以自己去试一下)
我们假设把一个2
2的方格像右延长一格:
在这里插入图片描述
再把它先按照2*2填上数字(字母)
在这里插入图片描述
因为红色格子左边的两个格子填上了2和3,所以这两个格一定得填1 4或4 1
在这里插入图片描述

由于22的格子有24种,红框内又有两种可能,所以23的方案种数就是24*2=48种。
在这里插入图片描述
同理,竖着也是一样。

那么怎么计算总和呢?
我们在填红蓝框的时候,有可能会出现一些重复和不成立的方案,
在这里插入图片描述
其实很简单就可以看出,问号所在的格子的其它周围的格子的值都是已知的,所以问号只能填1,其它也同理。

也就是说,红蓝框的方案数相加,由于图中“?”处的方案是确定的,所以要减1
而当n=2或m=2时由于它的框横向或纵向延长,所以不需要减去“?”处的1

最后,方案数公式:

  1. 当n=2且m=2时,ans=24
  2. 当n=2且m!=2时,ans=2m-2 *24
  3. 当m=2且n!=2时,ans=2n-2 *24
  4. 若非上述情况,则ans=(2n-2+2m-2-1) *24

.
.
.
.
.
程序:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

long long ksm(long long a,long long b,long long p)
{
	long long ans=1;
	for (;b;b>>=1)
	{
		if (b&1) ans=(long long)ans*a%p;
		a=(long long)a*a%p;
	}
	return ans;
}

int main()
{
	long long n,m,p=1000000007,ans;
	scanf("%lld%lld",&n,&m);
	if (n==2&&m==2) ans=24; else
	if (n==2) ans=((long long)ksm(2,m-2,p)*24)%p; else
	if (m==2) ans=((long long)ksm(2,n-2,p)*24)%p; else
	ans=((long long)ksm(2,n-2,p)+ksm(2,m-2,p)-1)*24%p;
	printf("%lld",ans);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值