题目本身很简单,拿出来主要是想说一下空间换时间,时间换空间的思维。
这题本来是递归的问题,但是递归会有大量重复计算。
所以采用一个数组存储临时结果,避免重复计算。
常规的递归算法改非递归算法的思路就是空间换时间。
这个在树、图的遍历中经常会出现,要求你采用非递归算法。
#include<stdio.h>
#include<stdlib.h>
int main(){
int a0,a1,p,q,k;
while(scanf("%d %d %d %d %d",&a0,&a1,&p,&q,&k)!=EOF){
int *a=(int *)calloc(k+1,sizeof(int));
a[0]=a0,a[1]=a1;
for(int i=2;i<=k;i++)
a[i]=(p*a[i-1]+q*a[i-2])%10000;
printf("%d\n",a[k]);
}
return 0;
}
#include<iostream> using namespace std; typedef long long INT; //算简单吗 int main() { INT a0,a1,p,q,k; while(cin>>a0>>a1>>p>>q>>k) //先按照常规思路 { INT result; if(k==0) { result=a0%10000; } else if(k==1) { result=a1%10000; } else { INT i=1; while(i<k) { result=(q*a0+p*a1)%10000; a0=a1; a1=result; i++; } } cout<<result<<endl; } return 0; }
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int a0 = scanner.nextInt(); int a1 = scanner.nextInt(); int p = scanner.nextInt(); int q = scanner.nextInt(); int k = scanner.nextInt(); int[] an = new int[k+1]; an[0]= a0; an[1]= a1; for (int i = 2; i <= k; i++) an[i]= (p*an[i-1]+q*an[i-2])%10000; System.out.println(an[k]); } }
/* 思路:矩阵递推公式: [An;An-1]=[p,q;0,1]^(k-1) *[A1;A0] */ #include <iostream> #include <valarray> using namespace std; typedef valarray<int> va; const int NUM =10000; va mod_pin(const va& v){ //矩阵平方 va val(4); val[0]=(v[0]*v[0]+v[1]*v[2])%NUM; val[1]=(v[0]*v[1]+v[1]*v[3])%NUM; val[2]=(v[2]*v[0]+v[3]*v[2])%NUM; val[3]=(v[2]*v[1]+v[3]*v[3])%NUM; return val; } va mod_chen(const va& v,const va& v1){//矩阵乘法 va val(4); val[0]=(v[0]*v1[0]+v[1]*v1[2])%NUM; val[1]=(v[0]*v1[1]+v[1]*v1[3])%NUM; val[2]=(v[2]*v1[0]+v[3]*v1[2])%NUM; val[3]=(v[2]*v1[1]+v[3]*v1[3])%NUM; return val; } int main(){ valarray<int> val(4); int a0,a1,p,q,k; cin>>a0>>a1>>p>>q>>k; //输入完毕 //矩阵初始化 val[0]=p; val[1]=q; val[2]=1; val[3]=0; val%=NUM; k--; //求val的k次方 va ans(1,4); ans[1]=0; ans[2]=0; while(k!=0){ if(k%2==1) ans = mod_chen(ans,val);//矩阵乘法 k=k>>1; val=mod_pin(val);//矩阵平方 } int an = (ans[0]*a1+ans[1]*a0)%NUM; cout <<an<<endl; return 0; }
#include <stdio.h> (737)#include <stdint.h> int main() { //freopen("data.txt", "r", stdin); int a[10000], p, q, k; scanf("%d%d%d%d%d", &a[0], &a[1], &p, &q, &k); for (int i = 2; i <= k; i++) { a[i] = (p * a[i - 1] + q * a[i - 2]) % 10000; } printf("%d\n", a[k]); return 0; }
#include<iostream> #include<cstdio> using namespace std; int main(){ int a[1000]; int p,q,k; while(cin>>a[0]>>a[1]>>p>>q>>k){ for(int i=2; i<=k; i++){ a[i] = (p*a[i-1]+q*a[i-2])%10000; } cout<<a[k]<<endl; } return 0; }
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a0 = sc.nextInt();
int a1 = sc.nextInt();
int p = sc.nextInt();
int q = sc.nextInt();
int k = sc.nextInt();
long [] a = new long [k+1];
a[0] = a0;
a[1] = a1;
for (int i = 2; i <= k; i++) {
a[i] = p * a[i - 1] + q * a[i - 2];
if(a[i]>100000) {
a[i] = a[i]% 10000;
}
}
System.out.println(a[k] % 10000);
}
}
直接算会超过long,所以对每个数都截断就好啦
import java.util.*; public class Main { public static void main(String[] args) { Scanner reader = new Scanner(System.in); while (reader.hasNext()) { int a0 = reader.nextInt(); int a1 = reader.nextInt(); int p = reader.nextInt(); int q = reader.nextInt(); int k = reader.nextInt(); long[] a = {a0, a1}; for (int i = 2; i <= k; ++i) { long tmp = p*a[1]%10000 + q*a[0]%10000; a[0] = a[1]; a[1] = tmp; } System.out.println(a[1]%10000); } } }
#include<stdio.h> int main(){ int a[2],p,q,k,res,i; for(;~scanf("%d %d %d %d %d",&a[0],&a[1],&p,&q,&k);printf("%d\n",res%10000)) for (res=k>1?0:a[k],i = 2; i <= k;i++) res = (q*a[0]+p*a[1])%10000,a[0]=a[1],a[1]=res; }
#include<stdio.h> const int mod=10000; struct Matrix{ long v[2][2]; void init(int a,int b,int c,int d){ v[0][0]=a,v[0][1]=b,v[1][0]=c,v[1][1]=d; } Matrix operator *(Matrix &tmp){ Matrix res; res.init(0,0,0,0); for(int i=0;i<2;++i) for(int j=0;j<2;++j) for(int k=0;k<2;++k){ res.v[i][j]+=v[i][k]*tmp.v[k][j]; res.v[i][j]%=mod; } return res; } }; Matrix pow(Matrix x,long y){ Matrix res; res.init(1,0,0,1); for(;y;y>>=1,x=x*x) if(y&1)res=res*x; return res; } int main(){ int a0,a1,p,q,k; while(scanf("%d%d%d%d%d",&a0,&a1,&p,&q,&k)!=EOF){ Matrix mat; mat.init(0,q,1,p); mat=pow(mat,k); long res=(a0*mat.v[0][0]+a1*mat.v[1][0])%mod; printf("%ld\n",res); } }//矩阵快速幂
#include "stdio.h" int main() { long a, b, ak; long a0, a1, p, q, k; while (scanf("%ld %ld %ld %ld %ld", &a0, &a1, &p, &q, &k) != EOF) { a = a1; b = a0; for (long i = 2; i <= k; i++) { if(i == 1)break; ak = (p*a + q*b)%10000; b = a; a = ak; } printf("%ld\n", a%10000 ); } return 0; }