【蓝桥杯】格子刷油漆

1、本题需要用到两个数组来实现递推,数组d,表示从一角出发,回到它对应的格子的方法数,数组a,表示从一角出发,遍历完所有格子(不一定回到对角)的方法数。

2、得出这个结论并不困难,只要在纸上画一个2*2的格子,走一遍就知道了。

3、先得出d的递推式子,再得出a的递推式子(见代码)。只要画出2*2的情况,写出这些递推式子不难。

4、最终答案等于4个角+中间。中间的话,可以选上方或下方格子为起点,因此乘以二,选好起点后,要确保一个是d,一个是a,而且对于每个d(或a)都有两种情况(两个角可以进入),因此最终答案乘以8.注意反之亦然(见代码)。

5、n为1的时候特判,计算时别忘了取模和使用long long。

#include<cstdio>
#include<iostream>
const int MOD=1000000007;
using namespace std;
int main(){
    long long a[1010]={0},d[1010]={0},n;
 scanf("%d",&n);
    d[1]=1;
 for(int i=2;i<=n;i++)
  d[i]=(d[i-1]*2)%MOD;
 a[1]=1;a[2]=6;
 for(int i=3;i<=n;i++){
  a[i]=(2*(d[i-1]+a[i-1]+2*a[i-2]))%MOD;
 }
 long long ans=0;
 if(n==1){
  printf("2\n");
  return 0;
 }else{
     ans=4*a[n]%MOD;
  for(int i=2;i<=n-1;i++){
   ans=(ans+8*(d[i-1]*a[n-i]))%MOD;
      ans=(ans+8*(d[n-i]*a[i-1]))%MOD;
  }
 }
 cout<<ans<<endl;
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值