UVA 12627 Erratic Expansion

博客介绍了UVA 12627题目的解题思路,讨论了一个红球在经过特定时间后会变成3红1蓝,蓝球会变成4个蓝球的情况。作者通过观察发现了问题的递归性质,并尝试了不同的解法,最终得出了一种涉及行和的递归公式来解决问题。虽然初始的直接递归和前缀和方法导致超时,但通过对规律的深入探究,作者找到了更有效的计算方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        题目大致意思为 告诉你一个红球为0时状态,已知一个红球每过一个时间会变为文档所示图中的3红1蓝,而蓝球每过一个时间则会变为4个蓝球。问在某一时刻,h1与h2之间的红球有几个。


       RT,这一题刚看到的时候毫无思路,仔细观察图后发现,发现肯定是递归。然后找递归公式。先说说我的想法历程,不想看的可以直接到后面看结论。


ijjh[i][j]i,ji表示时间,j表示第j行,h[i][j]表示i时,j行的红色气球
h[i][j]=h[i1][j>2i1?j2i1:j]2h[i][j]=h[i−1][j>2i−1?j−2i−1:j]∗2

    于是,我认为直接从开始的地方加到结束即可。


    当然妥妥的超时。。。。。。


    于是想维护前缀和,发现也不容易。突然发现行的递归能写,多半和的递归也能写。

找了一段时间的规律后,得出

if(j>2i1)if(j>2i−1)
s[i][j]=s[i][2i1]+s[i1][j2i1]s[i][j]=s[i][2i−1]+s[i−1][j−2i−1]
elseelse
s[i][j]=s[i1][j]2s[i][j]=s[i−1][j]∗2

     合并一下第一行,得到

s[i][j]=s[i1][2i1]2+s[i1][j2i1]s[i][j]=s[i−1][2i−1]∗2+s[i−1][j−2i−1]
又 发现
becauses[i][2i1]=3i12becauses[i][2i−1]=3i−1∗2
故得出代码

#include <stdio.h>
#define LL long long
LL QWQ[31];
LL QOQ[31];
LL QAQ(int i,int j){
    if(j==0)
        return 0;
    if(i==0&&j==1)
        return 1;
    if(j>QWQ[i-1])
        return (QOQ[i-1]<<1)+QAQ(i-1,j-QWQ[i-1]);
    else
        return QAQ(i-1,j)<<1;
}
int main(){
    //a[i][j]=a[i-1][j>2^(i-1)?j-2^(i-1):j]*2
    /*
     *
     * if(j>2^(i-1))
     *    a[i][j]=a[i-1][j-2^(i-1)]
     * else
     *    a[i][j]=a[i-1][j]*2
     * a[i][j]=a[i-1][]
     jmax=2^i;




     if(j>2^(i-1))
         s[i][j]=s[i][2^(i-1)]+s[i-1][j-2^(i-1)]
    else
        s[i][j]=s[i-1][j]*2

    s[i][j]=s[i-1][2^(i-1)]*2+s[i-1][j-2^(i-1)]
    because s[i][2^(i-1)]=3^(i-1)*2


     */
    //freopen("data.txt","r",stdin);
    //freopen("datas.txt","w",stdout);
    QWQ[0]=1;QOQ[0]=1;
    for(int i=1;i<31;i++)
        QWQ[i]=QWQ[i-1]*2;
    for(int i=1;i<31;i++)
        QOQ[i]=QOQ[i-1]*3;
    int T;
    scanf("%d",&T);
    int times=0;
    while(T--){
        times++;
        int k,a,b;
        LL sum=0;
        scanf("%d %d %d",&k,&a,&b);
        sum=QAQ(k,b)-QAQ(k,a-1);
        printf("Case %d: ",times);
        printf("%lld\n",sum);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值