贪心题,策略为将N划分成只有2和3,且在该条件下3尽可能多.
MS数学归纳法可证其正确性…
AC code:
#include <cstdio>
#include <cmath>
const int N=5010;
int n,w;
int a[N];
void gjdmul(int k)
{
int b[N]={0};
for(int i=1;i<=5000;i++)
{
b[i]+=a[i]*k;
b[i+1]+=b[i]/10;
b[i]%=10;
}
for(int i=1;i<=5000;i++) a[i]=b[i];
}
void qpow(int k)
{
if(!k)
{
a[1]=1;
return ;
}
qpow(k>>1);
int l;
int b[N]={0};
for(int i=5000;i>=1;i--)
{
if(a[i])
{
l=i;
break;
}
}
for(int i=1;i<=l;i++)
{
for(int j=1;j<=l;j++)
{
b[i+j-1]+=a[i]*a[j];
b[i+j]+=b[i+j-1]/10;
b[i+j-1]%=10;
}
}
for(int i=1;i<=5000;i++) a[i]=b[i];
if(k&1) gjdmul(3);
}
int main()
{
scanf("%d",&n);
if(n%3==0)
{
w=(int)((n/3)*log10(3))+1;
printf("%d\n",w);
qpow(n/3);
if(w<=100)
{
for(int i=w;i>=1;i--)
printf("%d",a[i]);
}
else
{
for(int i=w;i>=w-99;i--)
printf("%d",a[i]);
}
}
else if(n%3==1)
{
w=(int)(log10(4)+((n-4)/3)*log10(3))+1;
printf("%d\n",w);
qpow((n-4)/3);
gjdmul(4);
if(w<=100)
{
for(int i=w;i>=1;i--)
printf("%d",a[i]);
}
else
{
for(int i=w;i>=w-99;i--)
printf("%d",a[i]);
}
}
else
{
w=(int)(log10(2)+((n-2)/3)*log10(3))+1;
printf("%d\n",w);
qpow((n-2)/3);
gjdmul(2);
if(w<=100)
{
for(int i=w;i>=1;i--)
printf("%d",a[i]);
}
else
{
for(int i=w;i>=w-99;i--)
printf("%d",a[i]);
}
}
return 0;
}