UVa 12627 (递归 计数 找规律) Erratic Expansion

直接说几个比较明显的规律吧。

k个小时以后,红气球的个数为3k

单独观察一行:

令f(r, k)为k个小时后r行红气球的个数。

  • 如果r为奇数,f(r, k) = f((r+1)/2, k-1) * 2
  • 如果r为偶数,f(r, k) = f(r/2, k-1)

 

令g(r, k)为k个小时后r行红气球的个数。

  • 如果r为偶数,g(r, k) = g(r/2, k-1) * 3;
  • 如果r为奇数,g(r, k) = g(r-1, k) + f(r, k);

因此f和g都可以用递归求解。

 1 #include <cstdio>
 2 typedef long long LL;
 3 
 4 LL f(LL r, LL k)
 5 {
 6     if(k == 0) return 1LL;
 7     if(r & 1LL) return f((r+1)/2 ,k-1) * 2;
 8     else return f(r/2, k-1);
 9 }
10 
11 LL g(LL r, LL k)
12 {
13     if(r == 0) return 0;
14     if(k == 0) return 1LL;
15     LL ans = g(r/2, k-1) * 3;
16     if(r & 1) ans += f(r, k);
17     return ans;
18 }
19 
20 int main()
21 {
22     int T; scanf("%d", &T);
23     for(int kase = 1; kase <= T; kase++)
24     {
25         LL k, a, b;
26         scanf("%lld%lld%lld", &k, &a, &b);
27         printf("Case %d: %lld\n", kase, g(b, k) - g(a-1, k));
28     }
29 
30     return 0;
31 }
代码君

 

posted @ 2015-04-13 13:41  AOQNRMGYXLMV  阅读(357)  评论(0编辑  收藏  举报