• NOIP欢乐模拟赛 T2 解题报告


    小澳的坐标系

    coordinate.cpp/c/pas

    题目描述

    小澳者表也,数学者景也,表动则景随矣。

    小澳不喜欢数学,可数学却待小澳如初恋,小澳睡觉的时候也不放过。

    小澳的梦境中出现了一个平面直角坐标系,自原点,向四方无限延伸。

    小澳在坐标系的原点,他可以向上、向左或者向右走。他可以走n步,但不能经过相同的点

    小澳想知道他有多少种走法。

    输入格式

    输入文件名为coordinate.in。

    输入文件仅第一行一个正整数n,表示小澳可以走的步数。

     

    输出格式

    输出文件名为coordinate.out。

    输出文件共一行,输出一个正整数,表示答案(对10^9+7取模)。

     

    输入输出样例1

    coordinate.in

    coordinate.out

    2

    7

    【输入输出样例1说明】

    从(0,0)出发走2步,共7种走法:

    (0,0)->(0,1)->(0,2)

    (0,0)->(0,1)->(1,1)

    (0,0)->(0,1)->(-1,1)

    (0,0)->(1,0)->(2,0)

    (0,0)->(1,0)->(1,1)

    (0,0)->(-1,0)->(-2,0)

    (0,0)->(-1,0)->(-1,1)

     

    输入输出样例2

    coordinate.in

    coordinate.out

    3

    17

    数据规模与约定

    测试点编号

    n

    1~2

    n<=10

    3~4

    n<=100

    5~6

    n<=1000

    7~8

    n<=10^6

    9~10

    n<=10^9

    ————————————————————————分割线————————————————————————

    分析:

    看到这道题不难想到他的递推式

    在上图,蓝点表示只有两种走法的点,红点表示三种走法的点,红蓝相间表示两种都有。

    普通递推式如下 ( 80分 ):

    F[i][0]=F[i-1][0]+F[i-1][1]*2

    F[i][1]=F[i-1][0]+F[i-1][1] 

     

     1 #include "bits/stdc++.h"
     2 
     3 using namespace std ;
     4 typedef long long QAQ ;
     5 const int MOD = 1e9 + 7 ;
     6 
     7 int main ( ) {
     8         QAQ t1 = 1 , t2 = 3 , t3 = 3 , N ;
     9         cin >> N ;
    10         --N ;
    11         for ( int i=1 ; i<=N ; ++i ) {
    12                 t3 = ( t2 - t1 ) * 2 + t1 * 3 ;
    13                 t1 = t2 ;
    14                 t2 = t3 ;
    15         }    
    16         cout << t3 << endl ;
    17         return 0 ;
    18 }
    View Code

     

    但是,我们发现每一步只与上一步有关,可以建立递推关系,构造矩阵+快速幂解决。( AC )

     

     1 #include "bits/stdc++.h"
     2  
     3 using namespace std;
     4 typedef long long QAQ ;
     5 const int MOD = 1e9 + 7 ;
     6 
     7 struct Matrix{
     8         QAQ v[2][2];
     9         Matrix ( ) { memset ( v , 0 , sizeof ( v ) ) ; }
    10 }base , ans ;
    11 
    12 Matrix operator*( Matrix x , Matrix y ) {
    13         Matrix res;
    14         for(int i=0;i<2;i++)
    15         for(int j=0;j<2;j++)
    16         for(int k=0;k<2;k++)
    17                 (res.v[i][j]+=(x.v[i][k]*y.v[k][j]%MOD))%=MOD;
    18         return res;
    19 }
    20 
    21 int main ( ) {
    22         int N ;
    23         scanf ( "%d" , &N ) ; 
    24         ans.v[ 0 ][ 0 ] = 1 ;
    25         base.v[ 0 ][ 0 ] = base.v[ 0 ][ 1 ] = base.v[ 1 ][ 1 ] = 1 ;
    26         base.v[ 1 ][ 0 ] = 2 ;
    27         for ( int i=N + 1 ; i ; i>>=1 , base = base * base )
    28                 if  ( i & 1 ) ans = ans * base ;
    29         printf( "%I64d
    " , ans.v[0][0] ) ;
    30         return 0 ;
    31 }
    Matrix

    2016-10-03 21:42:08 

     PS:本题可以进一步化简递推,可得 f ( n ) = 2 * f ( n - 1 ) + f ( n - 2 ) ,也可得到答案。

    (完)

  • 相关阅读:
    JavaScript 严格模式
    JavaScript 编码规范 之 循环语句
    分享21个基于jquery菜单导航的效果
    揭秘:淘宝搜索排名真正规则和技巧
    11款网站死链检测工具
    收集Windows 8 Metro UI 风格网站资源,觉得不错的顶啊!!
    29个非常流行的jQuery提示信息插件
    分享14个很酷的jQuery导航菜单插件
    jquery select 常用操作总结
    必须去收藏14个响应式布局的前端开发框架
  • 原文地址:https://www.cnblogs.com/shadowland/p/5929581.html
Copyright © 2020-2023  润新知