列表

详情


NC19876. [AHOI2006]斐波卡契的兔子(KACCI)

描述

卡卡开始养兔子了!妈妈给他买了一对刚出生的兔子,卡卡了解到兔子的繁殖规律是这样的:才出生的一对兔子在一个月后将第一次生出一胎a对兔子,接着在出生后的二个月又将生出b对兔子,在第三个月和以后每个月都会繁殖c对兔子。(a ≤ b ≤ c) 由斐波纳契数列我们知道兔子的繁殖速度是很快的,然而卡卡有兔子一样多的好朋友,卡卡想在m个月后有k对兔子,以便分给他们的好友,他的愿望是否能够实现呢?
[任务] 编写一个程序:
从输入文件中读入输入信息;
计算m个月后卡卡将有多少对兔子,设之为P; 
计算如果m个月后卡卡要拥有至少k对兔子,那么开始时妈妈至少应该为卡卡购买多少对兔子,设之为Q; 
将结果输出至输出文件。

输入描述

输入文件的第一行有4个正整数:a, b, c和m;
而第二行则仅含一个正整数k。它们的含义见上文描述。

输出描述

你的程序将向输出文件输出两行,第一行是一个整数P而第二行是一个整数Q。

示例1

输入:

0 1 1 10
10000

输出:

89
113

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 397ms, 内存消耗: 26716K, 提交时间: 2023-07-28 23:02:23

#include<bits/stdc++.h>
using namespace std;
const int N=3001;
string f[N],sum[N];
int a[1000001];
inline string operator*(string x,int y){
    int len=x.size();
    for(int i=0;i<len;++i){
        a[i]=x[len-i-1]-'0';
        a[i]*=y;
    }
    a[len]=a[len+1]=a[len+2]=a[len+3]=a[len+4]=a[len+5]=0;
    for(int i=0;i<len;++i){
        if(a[i]>9){
            a[i+1]+=a[i]/10,a[i]%=10;
            if(i==len-1){
                ++len;
            }
        }
    }
    while(!a[len-1]&&len-1){
        --len;
    }
    string res="";
    for(int i=len-1;~i;--i){
        res+=char(a[i]+'0');
    }
    return res;
}
inline string operator+(string x,string y){
    int len=x.size(),ten=y.size();
    if(len<ten){
        swap(x,y);
        len^=ten^=len^=ten;
    }
    for(int i=0;i<len;++i){
        a[i]=x[len-i-1]-'0';
        if(ten-i>=1){
            a[i]+=(y[ten-i-1]-'0');
        }
    }
    a[len]=a[len+1]=a[len+2]=a[len+3]=a[len+4]=a[len+5]=0;
    for(int i=0;i<len;++i){
        if(a[i]>9){
            a[i+1]++,a[i]-=10;
            if(i==len-1){
                ++len;
            }
        }
    }
    while(!a[len-1]&&len-1){
        --len;
    }
    string res="";
    for(int i=len-1;~i;--i){
        res+=char(a[i]+'0');
    }
    return res;
}
inline string zhuan(int x){
	if(!x){
		return "0";
	}
	string res="";
	while(x){
		res=char(x%10+'0')+res;
		x/=10;
	}
	return res;
}
inline string operator-(string x,string y){
	int len=x.size(),ten=y.size();
	for(int i=0;i<len;++i){
		a[i]=x[len-i-1]-'0';
		if(ten-i>=1){
			a[i]-=(y[ten-i-1]-'0');
		}
	}
	for(int i=0;i<len;++i){
		if(a[i]<0){
			a[i]+=10,--a[i+1];
		}
	}
	while(!a[len-1]&&len){
		--len;
	}
	string res="";
	for(int i=len-1;~i;--i){
		res+=char(a[i]+'0');
	}
	return res;
}
inline bool operator>=(string x,string y){
	int len=x.size(),ten=y.size();
	if(len!=ten){
		return len>ten;
	}
	for(int i=0;i<len;++i){
		if(x[i]!=y[i]){
			return x[i]>y[i];
		}
	}
	return true;
}
inline string operator+(string x,int y){
	int len=x.size();
	for(int i=0;i<len;++i){
		a[i]=x[len-i-1]-'0';
	}
	a[len]=a[len+1]=a[len+2]=a[len+3]=a[len+4]=a[len+5]=0;
	++a[0];
	for(int i=0;i<len;++i){
		if(a[i]>9){
			++a[i+1],a[i]-=10;
			if(i==len-1){
				++len;
			}
		}
	}
	while(!a[len-1]&&len-1){
		--len;
	}
	string res="";
	for(int i=len-1;~i;--i){
		res+=char(a[i]+'0');
	}
	return res;
}
inline string calc(string x,string y){
	string res="",yu="";bool flag=0;
	int len=x.size();
	for(int i=0;i<len;++i){
		yu+=x[i];int tot=0;
		while(yu>=y){
			++tot;
			yu=yu-y;
		}
		if(flag){
			res+=char(tot+'0');
		}else{
			if(tot){
				flag=1;
				res+=char(tot+'0');
			}
		}
	}
	return yu==""?res:(res+1);
}
int main(){
    int a,b,c,m;
    scanf("%d%d%d%d",&a,&b,&c,&m);
    string k;
    cin>>k;
	f[0]="1";f[1]=zhuan(a);f[2]=zhuan(b+a*a);
    sum[0]="1",sum[1]=zhuan(a+1),sum[2]=zhuan(1+a+b+a*a);
	for(int i=3;i<=m;++i){
        f[i]=(sum[i-3]*c)+(f[i-2]*b)+(f[i-1]*a);
    	sum[i]=sum[i-1]+f[i];
	}
    cout<<sum[m]<<endl;
    cout<<calc(k,sum[m]);
    return 0;
}

C++14(g++5.4) 解法, 执行用时: 234ms, 内存消耗: 156408K, 提交时间: 2020-05-08 13:49:18

#include<bits/stdc++.h>
  
#define gm 1000
#define cas 10000000
#define max2 20050
  
int a[gm],b[gm],c[gm],k[gm],m,al,bl,cl,kl,t[gm],aa,bb,cc,r1[gm],r2[gm],r3[gm],l1,l2,l3;
int f[max2][gm],fl[max2],tf[max2][gm],tfl[max2],ans[gm],ansl,rrt[gm];
char tmp[10000];
  
inline void print(int *x,int xl)
{
    printf("%d",x[xl-1]);
    for(int i=xl-2;i>=0;i--)printf("%07d",x[i]);
}
  
inline int max(int a,int b)
{
    if(a>b)return a;else return b;
}
  
inline void add(int *x,int *y,int &xl,int yl)
{
    int ll=max(xl,yl);
    for(int i=0;i<ll;i++)
    {
        x[i]+=y[i];
        if(x[i]>=cas)x[i]-=cas,x[i+1]++;
    }
    if(x[ll])xl=ll+1;else xl=ll;
}
  
inline void addto(int *x,int *y,int *z,int xl,int yl,int &zl)
{
    zl=max(xl,yl);
    z[0]=0;
    for(int i=0;i<zl;i++)
    {
        z[i]+=x[i]+y[i];
        if(z[i]>=cas)z[i]-=cas,z[i+1]=1;else z[i+1]=0;
    }
    if(z[zl])zl++;
}
 
inline void multo(int *x,int y,int *z,int xl,int &zl)
{
    z[0]=0;
    for(int i=0;i<xl;i++)
    {
        z[i]+=x[i]*y;
        z[i+1]=z[i]/cas;
        z[i]%=cas;
    }
    if(z[xl])zl=xl+1;else zl=xl;
}
  
inline bool larger(int *x,int *y,int xl,int yl)
{
    if(xl>yl)return true;
    if(xl<yl)return false;
    for(int i=max(xl,yl)-1;i>=0;i--)
    {
        if(x[i]>y[i])return true;
        if(x[i]<y[i])return false;
    }
    return false;
}
  
inline void dec(int *x,int *y,int &xl,int yl)
{
    for(int i=0;i<xl;i++)
    {
        x[i]-=y[i];
        while(x[i]<0)x[i]+=cas,x[i+1]--;
    }
    while(xl&&!x[xl-1])xl--;
}
  
int main()
{
    al=1,bl=0,cl=0;
    a[0]=1;
    scanf("%d%d%d%d",&aa,&bb,&cc,&m);
    scanf("%s",tmp);
    int tml=strlen(tmp),tmp2=1;
    std::reverse(tmp,tmp+tml);
    kl=(tml+6)/7;
    for(int i=0;i<tml;i++)
    {
        if(i%7==0)tmp2=1;
        k[i/7]=k[i/7]+(tmp[i]-'0')*tmp2;
        tmp2*=10;
    }
    for(int i=0;i<m;i++)
    {
        multo(a,aa,r1,al,l1);
        multo(b,bb,r2,bl,l2);
        multo(c,cc,r3,cl,l3);
        add(c,b,cl,bl);
        memcpy(b,a,al*4);
        bl=al;
        addto(r1,r2,a,l1,l2,al);
        add(a,r3,al,l3);
    }
    add(a,b,al,bl);
    add(a,c,al,cl);
    print(a,al);
    printf("\n");
    memcpy(f[0],a,al*4);
    fl[0]=al;
    tf[0][0]=1;
    tfl[0]=1;
    ansl=0;
    int ma;
    for(ma=0;!larger(f[ma],k,fl[ma],kl);ma++)
    {
        multo(f[ma],2,f[ma+1],fl[ma],fl[ma+1]);
        multo(tf[ma],2,tf[ma+1],tfl[ma],tfl[ma+1]);
    }
    for(int i=ma-1;i>=0;i--)
    {
        if(!larger(f[i],k,fl[i],kl))
        {
            dec(k,f[i],kl,fl[i]);
            add(ans,tf[i],ansl,tfl[i]);
        }
    }
    if(kl)
    {
        rrt[0]=1;
        add(ans,rrt,ansl,1);
    }
    print(ans,ansl);
    printf("\n");
    return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 214ms, 内存消耗: 156492K, 提交时间: 2019-03-16 14:14:09

#include<bits/stdc++.h>
#define gm 1000
#define cas 10000000
#define max2 20050
int a[gm],b[gm],c[gm],k[gm],m,al,bl,cl,kl,t[gm],aa,bb,cc,r1[gm],r2[gm],r3[gm],l1,l2,l3;
int f[max2][gm],fl[max2],tf[max2][gm],tfl[max2],ans[gm],ansl,rrt[gm];
char tmp[10000];
inline void print(int *x,int xl)
{
    printf("%d",x[xl-1]);
    for(int i=xl-2;i>=0;i--)printf("%07d",x[i]);
}
inline int max(int a,int b)
{
    if(a>b)return a;else return b;
}
inline void add(int *x,int *y,int &xl,int yl)
{
    int ll=max(xl,yl);
    for(int i=0;i<ll;i++)
    {
        x[i]+=y[i];
        if(x[i]>=cas)x[i]-=cas,x[i+1]++;
    }
    if(x[ll])xl=ll+1;else xl=ll;
}
inline void addto(int *x,int *y,int *z,int xl,int yl,int &zl)
{
    zl=max(xl,yl);
    z[0]=0;
    for(int i=0;i<zl;i++)
    {
        z[i]+=x[i]+y[i];
        if(z[i]>=cas)z[i]-=cas,z[i+1]=1;else z[i+1]=0;
    }
    if(z[zl])zl++;
}
inline void multo(int *x,int y,int *z,int xl,int &zl)
{
    z[0]=0;
    for(int i=0;i<xl;i++)
    {
        z[i]+=x[i]*y;
        z[i+1]=z[i]/cas;
        z[i]%=cas;
    }
    if(z[xl])zl=xl+1;else zl=xl;
}
inline bool larger(int *x,int *y,int xl,int yl)
{
    if(xl>yl)return true;
    if(xl<yl)return false;
    for(int i=max(xl,yl)-1;i>=0;i--)
    {
        if(x[i]>y[i])return true;
        if(x[i]<y[i])return false;
    }
    return false;
}
inline void dec(int *x,int *y,int &xl,int yl)
{
    for(int i=0;i<xl;i++)
    {
        x[i]-=y[i];
        while(x[i]<0)x[i]+=cas,x[i+1]--;
    }
    while(xl&&!x[xl-1])xl--;
}
int main()
{
    al=1,bl=0,cl=0;
    a[0]=1;
    scanf("%d%d%d%d",&aa,&bb,&cc,&m);
    scanf("%s",tmp);
    int tml=strlen(tmp),tmp2=1;
    std::reverse(tmp,tmp+tml);
    kl=(tml+6)/7;
    for(int i=0;i<tml;i++)
    {
        if(i%7==0)tmp2=1;
        k[i/7]=k[i/7]+(tmp[i]-'0')*tmp2;
        tmp2*=10;
    }
    for(int i=0;i<m;i++)
    {
        multo(a,aa,r1,al,l1);
        multo(b,bb,r2,bl,l2);
        multo(c,cc,r3,cl,l3);
        add(c,b,cl,bl);
        memcpy(b,a,al*4);
        bl=al;
        addto(r1,r2,a,l1,l2,al);
        add(a,r3,al,l3);
    }
    add(a,b,al,bl);
    add(a,c,al,cl);
    print(a,al);
    printf("\n");
    memcpy(f[0],a,al*4);
    fl[0]=al;
    tf[0][0]=1;
    tfl[0]=1;
    ansl=0;
    int ma;
    for(ma=0;!larger(f[ma],k,fl[ma],kl);ma++)
    {
        multo(f[ma],2,f[ma+1],fl[ma],fl[ma+1]);
        multo(tf[ma],2,tf[ma+1],tfl[ma],tfl[ma+1]);
    }
    for(int i=ma-1;i>=0;i--)
    {
        if(!larger(f[i],k,fl[i],kl))
        {
            dec(k,f[i],kl,fl[i]);
            add(ans,tf[i],ansl,tfl[i]);
        }
    }
    if(kl)
    {
        rrt[0]=1;
        add(ans,rrt,ansl,1);
    }
    print(ans,ansl);
    printf("\n");
    return 0;
}

Python3 解法, 执行用时: 49ms, 内存消耗: 6996K, 提交时间: 2021-08-06 20:08:56

def mul(A, B, C):
    t = [[0, 0, 0], [0, 0, 0], [0, 0, 0]]
    for i in range(3):
        for j in range(3):
            for k in range(3):
                t[i][j] += B[i][k] * C[k][j];
    for i in range(3):
        for j in range(3):
            A[i][j] = t[i][j]
def get(x, y):
    ans = [[x, 0, 0], [0, 0, 0], [0, 0, 0]]
    base = [[a, 1, 0], [b, 0, 1], [c, 0, 1]]
    while y:
        if y & 1: mul(ans, ans, base)
        mul(base, base, base)
        y >>= 1
    return ans[0][0] + ans[0][1] + ans[0][2]

a, b, c, m = map(int, input().split())
k = int(input())
ans = get(1, m)
print(ans)
res = (k + ans - 1) // ans
print(res)

上一题