UVA - 12627 - Erratic Expansion(找规律递归)
递归找规律即可,用前b行减去前a-1行的红气球个数求解,细节见代码
1 #include<cstdio> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cctype> 5 #include<cmath> 6 #include<iostream> 7 #include<sstream> 8 #include<iterator> 9 #include<algorithm> 10 #include<string> 11 #include<vector> 12 #include<set> 13 #include<map> 14 #include<stack> 15 #include<deque> 16 #include<queue> 17 #include<list> 18 typedef long long ll; 19 typedef unsigned long long llu; 20 const int MAXN = 100 + 10; 21 const int MAXT = 10000 + 10; 22 const int INF = 0x7f7f7f7f; 23 const double pi = acos(-1.0); 24 const double eps = 1e-6; 25 using namespace std; 26 27 int k, a, b; 28 llu ans, c[40]; 29 30 //c存的是经过几次膨胀后所得的红气球总数 31 //每次膨胀过后,红气球总数*3 32 void init(){ 33 c[0] = 1; 34 for(int i = 1; i < 40; ++i) c[i] = c[i - 1] * 3; 35 } 36 37 llu dfs(int depth, int t){ 38 if(t <= 0) return 0; //如果层数小于等于0则不存在红气球 39 if(depth == 0) return 1; //如果膨胀0次则只有一个红气球 40 llu tmp = 1 << (depth - 1); //若膨胀depth-1次,tmp为行或列的大小 41 if(t >= tmp) return dfs(depth - 1, t - tmp) + 2 * c[depth - 1]; 42 //若现在所处行超过了tmp,则把四个depth-1中的顶上两个取出 43 //然后加剩余一个的前t-tmp行 44 else return 2 * dfs(depth - 1, t); 45 //否则,就取四个depth-1上的顶上两个的前t行即可 46 } 47 48 int main(){ 49 init(); 50 int T; 51 scanf("%d", &T); 52 for(int ca = 1; ca <= T; ++ca){ 53 scanf("%d%d%d", &k, &a, &b); 54 ans = dfs(k, b) - dfs(k, a - 1); //答案为膨胀k次前b行的个数 - 膨胀k次前a-1行的个数 55 printf("Case %d: %llu\n", ca, ans); 56 } 57 return 0; 58 }