经典算法(C++版)快速幂函数(内含详细解释>^<)

题目

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就可以做出来了吧,答案不放在文章中了,大家下去自己去看看吧<..>  <=>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值