您的位置:首页 > 其它

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

2016-06-15 21:29 447 查看
递归找规律即可,用前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;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  uva