UVA12627-Erratic Expansion(递归)
Problem UVA12627-Erratic Expansion
Accept: 465 Submit: 2487
Time Limit: 3000 mSec
Problem Description
Input
The first line of input is an integer T (T < 1000) that indicates the number of test cases. Each case contains 3 integers K, A and B. The meanings of these variables are mentioned above. K will be in the range [0,30] and 1 ≤ A ≤ B ≤ 2K.
Output
For each case, output the case number followed by the total number of red balloons in rows [A,B] after K-th hour.
Sample Input
3
0 1 1
3 1 8
3 3 7
Sample Output
Case 1: 1
Case 2: 27
Case 3: 14
题解:本来想找规律,但是纯粹找规律不太好找,参考了一下lrj的思路,设g(k,i)为k小时后第i行及以下的红气球个数,这样递归方程就很好推了(详见代码),红气球的个数很显然是3^k,还有一个注意的点是,举个例子,k=2,则此时最多4行,如果求第5行及以下的气球数,直接返回0即可。
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long LL; 5 6 const int maxn = 50; 7 8 int k, a, b; 9 int two_pow[maxn]; 10 LL tri_pow[maxn]; 11 12 LL g(int k, int i) { 13 if (i > two_pow[k]) return 0LL; 14 if (k == 0) return 1LL; 15 if (i > two_pow[k - 1]) { 16 return g(k - 1, i - two_pow[k - 1]); 17 } 18 else { 19 return 2 * g(k - 1, i) + tri_pow[k - 1]; 20 } 21 } 22 23 int main() 24 { 25 //freopen("input.txt", "r", stdin); 26 int iCase; 27 scanf("%d", &iCase); 28 two_pow[0] = 1; 29 tri_pow[0] = 1LL; 30 for (int i = 1; i <= 30; i++) { 31 two_pow[i] = two_pow[i - 1] * 2; 32 tri_pow[i] = tri_pow[i - 1] * 3; 33 } 34 35 int con = 1; 36 37 while (iCase--) { 38 scanf("%d%d%d", &k, &a, &b); 39 printf("Case %d: %lld\n", con++, g(k, a) - g(k, b + 1)); 40 } 41 42 return 0; 43 }