题目
David has a white board with 2×N grids.He decides to paint some grids black with his brush.He always starts at the top left corner and ends at the bottom right corner, where grids should be black ultimately.
Each time he can move his brush up(↑
), down(↓
), left(←
), right(→
), left up(↖
), left down(↙
), right up(↗
), right down (↘
) to the next grid.
For a grid visited before,the color is still black. Otherwise it changes from white to black.
David wants you to compute the number of different color schemes for a given board. Two color schemes are considered different if and only if the color of at least one corresponding position is different.
Input
One line including an integer n(0<n ≤1,000,000,000)
Output
One line including an integer, which represent the answer mod 1000000007
样例1
输入
2
输出
4
样例解释1
样例2
输入
3
输出
12
样例解释2
解题思路
此题是我入算法课程的第一题,老师说牛刀小试一下,此题不给出答案,只有思路,也是希望大家也多想一想怎么做,而不是搬过来应付.好了,废话少说,进入正题。
找规律:(1) 根据2*N,易知行数为2不会改变,列数会根据N而改变。
(2)根据题目意思,从左上角开始涂黑到右下角结束,可以上下左右,左上,左下,右上,右下,移动。
(3)也就是说,第一列和最后一列有两种情况,第一列:要么上面为黑色,要么两块都是黑色;最后一列:要么下面为黑色,要么都为黑色。而中间所有列的规律是一样的:要么上面为黑色,要么下面为黑色,要么都为黑色,这三种情况。
(4)因为第一列和最后一列情况为两种,所以为2*2,中间都有三种情况,所以未(N-2)个3相乘,即3^(N-2),所有列情况相乘,即为4*3^(N-2)。
(5)带几个数字验证以下,发现1不符合规律,所以4*3^(N-2) (N>1),N=1时,情况为1种。
(n6)所以,在运用规律的时候要把N=1单独拿出来。
快速幂:常规思路写代码要么用个pow函数,要么for循环一下,时间复杂度为O(n),我提交代码的时候就发现只有前两个是对的,所以我就找啊找啊,还是没找到,后来发现了快速幂,这个方法使时间复杂度降低很多,变为了O(log(n)),诸位看官一看就知道降低好多,毕竟它们的图形很容易画出来。
现在我写一下时间复杂度为O(n)的复杂度的代码:
#include <iostream>
#include<math.h>
using namespace std;
int main()
{
int n;
cin>>n;
if(n>0)
{
if(n==1)
{cout<<1;}
if(n>1)
{
int c;
c=pow(3,(n-2))*4;
cout<<c;
}
}
}
这个大家基本上都会写,当然也可以用for做,当然,用快速幂的方法是更加的快速的,这里我卖个关子,先不给大家写出本题答案,大家根据快速幂的定义及其过程去看一下。
本题由规律得出的公式为4*3^(n-2),我们先以3^10为例,正常算法是for循环一遍,抑或是用pow函数去做,你看这样是不是更快的算:将3^(10)改为3^(2*5),即变为了9*(5),这样看是不是幂降低一半,将一个9拿出来后变为9^4,然后再按照刚才的算法会变为9*81^2,单独拿出来的这个9别忘了乘进去,这样看来,只需要一步..两步....三步,哈哈,只要三步乘法就可以做出来,是不是比循环少了很多,计算量大大减轻,这个算法的复杂度就变为了O(log(n)),这个懂了之后,代码随便用个while就可以做出来了吧,答案不放在文章中了,大家下去自己去看看吧<..> <=>