• UVa 12627 Erratic Expansion


     因为不好复制题目,就出给出链接吧:

    Vjudge传送门[here]

    UVa传送门[here]


       请仔细看原题上的那幅图,你会发现,在时间t(t > 0),当前的气球构成的一幅图,它是由三个时间为(t - 1)的图再加上一块全是蓝色的一块构成。所以可以想到递归求解。对于上半部分的行求前一时刻对应几行的红球数乘2,下面的减去2t - 1然后递归前一幅图求解。

      但是这样最坏的时间复杂度为O(2k-1),仍然会TLE,那么得另寻出路。如果求在时刻t整个一幅图的红球个数,那么可以直接算出来,个数为3k

      因此在递归的过程中特判一下是不是求整个图的红球个数,可以把时间复杂度将为?O(log2n)

    Code

     1 /**
     2  * UVa
     3  * Problem#12627
     4  * Accepted
     5  * Time:0ms
     6  */
     7 #include<iostream>
     8 #include<cstdio>
     9 #include<cctype>
    10 #include<ctime>
    11 #include<cstring>
    12 #include<cstdlib>
    13 #include<fstream>
    14 #include<sstream>
    15 #include<algorithm>
    16 #include<map>
    17 #include<set>
    18 #include<stack>
    19 #include<queue>
    20 #include<vector>
    21 #include<stack>
    22 #ifndef WIN32
    23 #define AUTO "%lld"
    24 #else
    25 #define AUTO "%I64d"
    26 #endif
    27 using namespace std;
    28 typedef bool boolean;
    29 #define inf 0xfffffff
    30 #define smin(a, b) a = min(a, b)
    31 #define smax(a, b) a = max(a, b)
    32 template<typename T>
    33 inline void readInteger(T& u){
    34     char x;
    35     int aFlag = 1;
    36     while(!isdigit((x = getchar())) && x != '-');
    37     if(x == '-'){
    38         x = getchar();
    39         aFlag = -1;
    40     }
    41     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
    42     ungetc(x, stdin);
    43     u *= aFlag;
    44 }
    45 
    46 int T;
    47 int n, a, b;
    48 
    49 template<typename T>
    50 T pow(T a, int pos) {
    51     if(pos == 0)    return 1;
    52     if(pos == 1)    return a;
    53     T temp = pow(a, pos / 2);
    54     if(pos & 1)        return temp * temp * a;
    55     return temp * temp;
    56 }
    57 
    58 inline void init() {
    59     readInteger(n);
    60     readInteger(a);
    61     readInteger(b);
    62 }
    63 
    64 long long dfs(int dep, int top, int bottom) {
    65     if(dep == 0)    return 1;
    66     if(top == 1 && bottom == (1 << dep))    return pow((long long)3, dep);
    67     int mid = 1 << (dep - 1);
    68     if(bottom <= mid)    return 2 * dfs(dep - 1, top, bottom);
    69     if(top > mid)    return dfs(dep - 1, top - mid, bottom - mid);
    70     return 2 * dfs(dep - 1, top, mid) + dfs(dep - 1, 1, bottom - mid);
    71 }
    72 
    73 inline void solve() {
    74     long long res = dfs(n, a, b);
    75     printf(AUTO"
    ", res);
    76 }
    77 
    78 int main() {
    79     readInteger(T);
    80     for(int kase = 1; kase <= T; kase++) {
    81         init();
    82         printf("Case %d: ", kase);
    83         solve();
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    线段树
    哈希,hash
    单调栈
    树的重心
    背包问题
    最小生成树
    二分图匹配
    题解 P6355 [COCI2007-2008#3] DEJAVU
    题解 P6745 『MdOI R3』Number
    题解 P2080 增进感情
  • 原文地址:https://www.cnblogs.com/yyf0309/p/6661581.html
Copyright © 2020-2023  润新知