题解、Writeup、游记和碎碎念
卡卡开始养兔子了!妈妈给他买了一对刚出生的兔子,卡卡了解到兔子的繁殖规律是这样的:才出生的一对兔子在一个月后将第一次生出一胎 a 对兔子,接着在出生后的二个月又将生出 b 对兔子,在第三个月和以后每个月都会繁殖 c 对兔子。(a <= b <= c) 由斐波纳契数列我们知道兔子的繁殖速度是很快的,然而卡卡有兔子一样多的好朋友,卡卡想在 m 个月后有 k 对兔子,以便分给他们的好友,他的愿望是否能够实现呢?
[任务] 编写一个程序:从输入文件中读入输入信息;计算 m 个月后卡卡将有多少对兔子,设之为 P;计算如果 m 个月后卡卡要拥有至少 k 对兔子,那么开始时妈妈至少应该为卡卡购买多少对兔子,设之为 Q;将结果输出至输出文件。
输入文件的第一行有 4 个正整数:a, b, c 和 m;而第二行则仅含一个正整数 k。它们的含义见上文描述。
你的程序将向输出文件输出两行,第一行是一个整数 P 而第二行是一个整数 Q。
0 1 1 10
10000
89
113
0 <= a <= b <= c <= 100, 1 <= m <= 3 000, 1 <= k <= 10^6000
我们用 表示一个月、两个月、三个月及以上的兔子,那么每次 就可以求出 ,而 就是 向上取整。
可以用 去求。
然而为什么 AC 的人这么少呢。。
#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;
}
日期: 2016-09-13
这是一篇旧文,原始文章及评论可在 https://oldblog.mcfx.us/archives/24/ 查看。