UVA - 12627 - Erratic Expansion(找规律递归)


递归找规律即可,用前b行减去前a-1行的红气球个数求解,细节见代码



#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
typedef long long ll;
typedef unsigned long long llu;
const int MAXN = 100 + 10;
const int MAXT = 10000 + 10;
const int INF = 0x7f7f7f7f;
const double pi = acos(-1.0);
const double eps = 1e-6;
using namespace std;

int k, a, b;
llu ans, c[40];

//c存的是经过几次膨胀后所得的红气球总数
//每次膨胀过后,红气球总数*3
void init(){
    c[0] = 1;
    for(int i = 1; i < 40; ++i)  c[i] = c[i - 1] * 3;
}

llu dfs(int depth, int t){
    if(t <= 0)  return 0;          //如果层数小于等于0则不存在红气球
    if(depth == 0)  return 1;      //如果膨胀0次则只有一个红气球
    llu tmp = 1 << (depth - 1);    //若膨胀depth-1次,tmp为行或列的大小
    if(t >= tmp)  return dfs(depth - 1, t - tmp) + 2 * c[depth - 1];
                        //若现在所处行超过了tmp,则把四个depth-1中的顶上两个取出
                        //然后加剩余一个的前t-tmp行
    else  return 2 * dfs(depth - 1, t);
                        //否则,就取四个depth-1上的顶上两个的前t行即可
}

int main(){
    init();
    int T;
    scanf("%d", &T);
    for(int ca = 1; ca <= T; ++ca){
        scanf("%d%d%d", &k, &a, &b);
        ans = dfs(k, b) - dfs(k, a - 1);   //答案为膨胀k次前b行的个数 - 膨胀k次前a-1行的个数
        printf("Case %d: %llu\n", ca, ans);
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值