UVa 12627 - Erratic Expansion
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4352
题意:
一开始有1个红气球。每小时后,1个红气球会变成3个红气球和1个蓝气球,而1个蓝气球会变成4个蓝气球。
问:经过k小时后,第A~B行一共有多少个红气球?例如,k=3,A=3,B=7,答案为14。
分析:
设 sum(k,i) 表示k小时后第1~i行的红气球总数,R表示2的k次方,M表示R的中点(即R>>1)。
可以发现,当 i = R 时,sum(k,i) = sum(k-1,M) * 3;
当 i <= M 时,sum(k,i) = sum(k-1,i) * 2;
当 i > M 时,sum(k,i) = sum(k-1,M) * 2 + sum(k-1,i-M)。
递归求解即可,k小时后第A~B行的红气球总数为 sum(k,B) - sum(k,A-1) 。
代码:
1 #include <cstdio> 2 3 typedef long long int LLI; 4 5 LLI sum(LLI k, LLI i){ 6 if(k == 0) return i == 1; 7 LLI R = 1LL << k, M = 1LL << k - 1; 8 if(i == R) return sum(k - 1, M) * 3; 9 if(i <= M) return sum(k - 1, i) * 2; 10 return sum(k - 1, M) * 2 + sum(k - 1, i - M); 11 } 12 13 int main(){ 14 int T, cases = 1; 15 scanf("%d", &T); 16 while(T--){ 17 LLI k, a, b; 18 scanf("%lld%lld%lld", &k, &a, &b); 19 printf("Case %d: %lld\n", cases++, sum(k, b) - sum(k, a - 1)); 20 } 21 return 0; 22 }