[BZOJ1263][SCOI2006]整数划分

8 篇文章 0 订阅

原题地址

贪心题,策略为将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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值