小澳的坐标系

题目描述

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

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

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

小澳在坐标系的原点,他可以向上、向左或者向右走。他可以走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

 


 思路:

我的20分暴搜……

#include<stdio.h>
int ans,n;
int dx[]={-1,1,0},dy[]={0,0,1};
bool vis[1001][1001];
void dfs(int x,int y,int step)
{
    if(step==n) {
        ans++;
        return ;
    }
    
    for(int i=0;i<3;++i) {
        int nx=x+dx[i];
        int ny=y+dy[i];
        if(vis[nx][ny]) continue;
        vis[nx][ny]=true;
        dfs(nx,ny,step+1);
        vis[nx][ny]=0;
    }
}

int main()
{
//    freopen("coordinate.in","r",stdin),freopen("coordinate.out","w",stdout);
    scanf("%d",&n);
    vis[201][0]=1;
    dfs(201,0,0);
    printf("%d",ans);
    return 0;
}

 

80分-code

#include<stdio.h>
#include<algorithm> 
using namespace std;
const int P=12345;
long long n,f[2][3];
 
int main() 
{
    scanf("%lld",&n);
    f[0][0]=1;
    for(int i=1;i<=n;++i) {
        f[i&1][0]=(f[(i-1)&1][0]%P+f[(i-1)&1][1]%P+f[(i-1)&1][2]%P)%P;
        f[i&1][1]=(f[(i-1)&1][1]%P+f[(i-1)&1][0]%P)%P;
         f[i&1][2]=(f[(i-1)&1][2]%P+f[(i-1)&1][0]%P)%P;
    }
    if(n&1) printf("%lld",(f[1][1]%P+f[1][2]%P+f[1][0]%P)%P);
    else printf("%lld",(f[0][1]%P+f[0][2]%P+f[0][0]%P)%P);
    return 0;
}

 

正解做法(矩阵乘法)

#include<stdio.h>
#include<string.h>
const long long mod=1e9+7;
struct X
{
    long long f[2][2];
    X() {memset(f,0,sizeof(f));};
};
X xc(X a,X b)
{
    X re;
    for(int i=0;i<2;i++)
        for(int j=0;j<2;j++)
        {
            for(int k=0;k<2;k++)
                re.f[i][j]+=a.f[i][k]*b.f[k][j];
            if(re.f[i][j]>=mod) re.f[i][j]%=mod;
        }
    return re;
}
int main()
{
//    freopen("coordinate.in","r",stdin),freopen("coordinate.out","w",stdout);
    long long n;
    while(scanf("%lld",&n)!=EOF)
    {
        X a;
        if(n==1) 
        {
            printf("3");
            continue;
        }
        else if(n==2)
        {
            printf("7");
            continue;
        }
        n-=3;
        a.f[0][1]=a.f[1][0]=1;
        a.f[1][1]=2;
        for(X b=a;n>0;n>>=1,b=xc(b,b))
            if(n&1) a=xc(a,b);
        printf("%lld\n",(a.f[1][1]*7+a.f[1][0]*3)%mod);
    }
    return 0;
}

 

posted @ 2018-08-21 20:56  qseer  阅读(255)  评论(0编辑  收藏  举报