算法竞赛入门经典 例题8-12 奇怪的气球膨胀 Erratic Expansion uva12627

  题目:https://vjudge.net/problem/UVA-12627


思路:图形的变化很有规律,可以看出下一个图形是由3个上一个图形和右下方蓝色的的正方形组成。


我定义了一个函数bottum用于求k小时时倒数u行红气球总数,那么作差就可以求出A到B行之间红气球的数量。

可以看出满足以下规律。

(1)当u=0时个数为0。

(2)当u属于图形下半部分时,k小时的个数与k-1小时的个数相同。

(3)当u属于图形上半部分时,属于下半部分的红气球个数与k-1时个数相同,剩余部分与k-1时u-边长len/2时的个数相同。

(4)k=0,u=1时红气球个数为1。

定义函数amount求整个图形红气球总数

满足:

(1)k=0时,个数为1。

(2)amount(k) *= amount(k-1)。


代码:c++

#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;

long long amount(int k)//k小时时红气球总数
{
    return k?3*amount(k-1):1;
}

long long bottum(int u, int k)//计算倒数u行的红气球总数
{
    long long len = round(pow(2, k));
    if(u==0)
    {
        return 0;
    }
    if(u==len)
    {
        return amount(k);
    }
    if(k==0)
    {
         return 1;
    }
    if(u<=len/2)
    {
        return bottum(u, k-1);
    }
    else
    {
        return 2*bottum(u-len/2, k-1) + amount(k-1);
    }
}

int main()
{
    int T, cases = 1, a, b, k;
    cin >> T;
    while(T--)
    {
        scanf("%d%d%d", &k, &a, &b);
        long long len = round(pow(2, k));
        long long ans = bottum(len-a+1, k) - bottum(len-b, k);
        printf("Case %d: %lld\n", cases++, ans);
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值