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 }

猜你喜欢

转载自www.cnblogs.com/npugen/p/9672284.html