https://vjudge.net/problem/UVA-12627
找规律。用 f(k,i)表示:第 k 小时最上面 i 行有多少红球。
找a-b行红球的数量,也就是求 f(k,b) - f(k,a-1)。k 时刻的状态是和 k-1的状态紧密相关的。k 时刻状态是 3 个 k-1时刻的状态(分别位于左上,左下,右上),右下全是蓝色球。所以,
当 i <= 2^(k-1),等于左上和右上的两个(k-1)状态,即:f(k,i) = 2 * f(k-1, i - 2(k-1)) ;
当 i > 2^(k-1),等于完整的左上,右上加上部分左下,f(k,i) = f(k-1, i - 2(k-1)) + 2 * 3^(k-1);
注意:3的k-1次方直接用pow函数会错误,因为会int越界,应该存在一个数组里!。
#include <cstdio>
#include <cmath>
typedef long long LL;
LL temp[31];
// 第 k小时,最上面 i 行的红球数量
LL f(LL k, LL i){
if(i <= 0) return 0;
if(k == 0) return 1;
if(i > pow(2,k-1))
return f(k - 1, i - pow(2,k-1)) + 2 * temp[k-1];
else
return 2*f(k - 1, i);
}
int main()
{
//freopen("in.txt","r",stdin);
temp[0] = 1;
for(int i = 1; i <= 30; ++i) temp[i] = temp[i-1] * 3;
int T; scanf("%d",&T);
LL k,a,b;
int kase = 1;
while( T-- ){
scanf("%lld %lld %lld",&k,&a,&b);
printf("Case %d: %lld\n",kase++,f(k,b)-f(k,a-1));
}
return 0;
}