题目链接:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&category=844&problem=4352&mosmsg=Submission+received+with+ID+15396764
#include <cstdio>
#include <cmath>
using namespace std;
long long K, A, B;
long long get_num(long long x, long long i);
int main()
{
int T;
scanf("%d", &T);
int count = 0;
while(count < T)
{
scanf("%lld %lld %lld", &K, &A, &B);
/*
long long sum = 0;
// 依次计算每个行的红色气球数
for(long long i = A; i <= B; i++)
sum = sum + get_num(K, i);
*/
printf("Case %d: %lld\n", count+1, get_num(K,B)-get_num(K,A-1));
count++;
}
return 0;
}
// 计算第i行及以上的红色气球数
// x代表第x个小时,i代表第i行
long long get_num(long long x, long long i)
{
if(i == 0)
return 0;
if(x == 0 && i == 1)
return 1;
/*
if(i % 2 == 1)
{
return 2*get_num(x-1, (i+1)/2);
}
else
{
return get_num(x-1,i/2);
}
*/
if(i > pow(2, x-1))
{
return get_num(x-1, i-pow(2, x-1)) + 2*pow(3, x-1);
}
else
return 2*get_num(x-1, i);
}
/*
// 依次计算每个行的红色气球数
// x代表第x个小时,i代表第i行
long long get_num(long long x, long long i)
{
if(x == 0 && i == 1)
return 1;
if(i % 2 == 1)
{
return 2*get_num(x-1, (i+1)/2);
}
else
{
return get_num(x-1,i/2);
}
}
*/
一开始的想法是递归计算第i行的红色气球总数,然后将A到B行的红色气球数相加。超时。
后来没做出来,看了答案发现,考虑的角度是计算第i行及其以上的红色气球总数,然后用B行及以上减去A-1行及以上的红色气球总数就可以了。
下次再遇到这样的情况,应该学着转变思路想想头和尾的情况,然后再处理。
本文探讨了通过转变思路优化递归计算方法,避免超时问题,并详细介绍了利用头和尾情况处理来简化问题的方法。同时,文章还强调了在解决类似问题时,灵活思考的重要性。
625

被折叠的 条评论
为什么被折叠?



