题目: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;
}