【题目描述】
小澳者表也,数学者景也,表动则景随矣。
小澳不喜欢数学,可数学却待小澳如初恋,小澳睡觉的时候也不放过。
小澳的梦境中出现了一个平面直角坐标系,自原点,向四方无限延伸。
小澳在坐标系的原点,他可以向上、向左或者向右走。他可以走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; }