zoukankan      html  css  js  c++  java
  • 2012 MUTC 6 总结

    题解链接:http://page.renren.com/601081183/note/865145486?ref=minifeed&sfet=2012&fin=1&ff_id=601081183&feed=page_blog&tagid=865145486&statID=page_601081183_2&level=1

      第五场组队赛了,这次的水题(题解叫签到题)过的很顺利,因为一点难度都没有,一眼就看出了做法,而全场就只出了那么两题....而我就只负责其中一题,和另外一题的做法。

      这次多校联赛,刚开始了好几分钟,大board居然没有人过题,搞到都不知道哪题可以做了...不过其实1001就是水题,不过负责看那题的队友居然没发现,原因是看不懂题目.....- -!然后我看了题以后,发现是一个大水模拟题,于是今天打算再次鼓励队友,让他赶紧过了。结果,在打了几分钟以后,他居然搞出了个挺凌乱的代码,于是我在一旁就揪心了...最后不忍放过水题,再次一手抢过键盘敲了起来........不过,做的时候忽略了一些小问题,例如 模0 了,于是我就意外的RE了一次T^T!改过来以后就AC了~

      在我打上面这题的时候,我顺便看了一下1006,想了一下就想到是三分了...不过其实那时我没想清楚怎么证明是三分,赛后才跟大牛交流的时候才发觉,原来证明起来好像挺麻烦的..- -   不过幸亏当时没考虑太多,才能以最快的速度告诉队友这个的做法,然后在他敲三分的时候我就上了个厕所了~ 回来以后,真的AC了.....  

      然后就是1008,一道挺有技巧的题,不过当时还真的没发现奇偶性的规律,所以没有做出....

      其实后面的三个多钟,我们一直在讨论1010,因为觉的这个递推是可以做的.....终于,在只剩一个钟的时候,把思路理清了,代码也写了个记忆化dfs,可惜的是,这样做会超时,而且是一定会超的......然后,我们居然花了半多个钟才把它改成dp,这是何等低的代码速度....囧!

      按照思路改了dp后,测试的时候发现,预处理的时间是多么的漫长,于是我们在仅余的十来分钟里对它进行剪枝....不过最后两三分钟才发现要记忆化dp的部分过程,随后来不及改了,所以带着遗憾结束了比赛.....

      看了题解,题解对我们合作讨论出来的那题贴上了简单题的标签...................于是我就觉得,我真的应该尽快看懂,搞熟练递推类的题目!不能让这种“简单题”挡住我前进的步伐的!!!

    更新:添加1010的代码  hdu 3459

    View Code
      1 #include <cstdio>
      2 #include <cstring>
      3 #include <iostream>
      4 #include <cstdlib>
      5 #include <cmath>
      6 using namespace std;
      7 
      8 #define debug 0
      9 
     10 typedef __int64 ll;
     11 
     12 const ll mod = 1000000007;
     13 const int maxn = 365;
     14 ll dp[maxn][maxn], ss[maxn][maxn]; // ss用于储存前k项和
     15 ll cc[maxn][maxn]; // cc用于储存组合数
     16 int lg[maxn];
     17 
     18 int min2(int a, int b){return a < b ? a : b;}
     19 int max2(int a, int b){return a > b ? a : b;}
     20 
     21 void get_c(){ // 用杨辉三角递推上去
     22     memset(cc, 0, sizeof(cc));
     23     memset(ss, 0, sizeof(ss));
     24     cc[0][0] = cc[1][0] = cc[1][1] = 1;
     25     for (int i = 2; i < maxn; i++){
     26         cc[i][0] = 1;
     27         for (int j = 1; j <= i; j++){
     28             cc[i][j] = (cc[i - 1][j] + cc[i - 1][j - 1]) % mod;
     29         }
     30     }
     31     //printf("%I64d  %I64d\n", cc[4][2], cc[5][2]);
     32 }
     33 
     34 void init(){
     35     lg[0] = 0;
     36     for (int i = 1; i < maxn; i++){
     37         lg[i] = (int)floor(log10((double)i) / log10((double)2)) + 1;
     38     }
     39     memset(dp, 0, sizeof(dp));
     40     ss[0][0] = dp[0][0] = 1;
     41     dp[1][1] = 1;
     42     dp[2][2] = 4;
     43     for (int i = 1; i < maxn; i++){
     44         ss[0][i] = ss[1][i] = 1;
     45         ss[2][i] = 4;
     46     }
     47     ss[2][1] = 0;
     48 }
     49 
     50 ll perm(int a){
     51     ll ret = 1;
     52 
     53     for (ll i = 2; i <= a; i++){
     54         ret *= i;
     55         ret %= mod;
     56     }
     57 
     58     return ret;
     59 }
     60 
     61 void pre(){
     62     ll tmp1, tmp2;
     63 
     64     for (int n = 3; n <= 360; n++){
     65         for (int k = lg[n]; k <= n; k++){
     66             for (int i = 0; i <= n - 1; i++){
     67                 tmp1 = tmp2 = 0;
     68                 if (dp[n - i - 1][k - 1]){
     69                     if (lg[i]) tmp1 = ss[i][min2(k - 2, i)] - ss[i][lg[i] - 1];
     70                     else tmp1 = ss[i][min2(k - 2, i)];
     71                     tmp1 %= mod;
     72                     tmp1 *= dp[n - i - 1][k - 1];
     73                     tmp1 %= mod;
     74                 } // 枚举右子树满的情况
     75                 if (dp[i][k - 1]){
     76                     if (lg[n - i - 1]) tmp2 = ss[n - i - 1][min2(k - 2, n - i - 1)] - ss[n - i - 1][lg[n - i - 1] - 1];
     77                     else tmp2 = ss[n - i - 1][min2(k - 2, n - i - 1)];
     78                     tmp2 %= mod;
     79                     tmp2 *= dp[i][k - 1];
     80                     tmp2 %= mod;
     81                 } // 枚举左子树满的情况
     82                 if (i != n - 1){
     83                     dp[n][k] += (((tmp1 + tmp2) % mod) * cc[n - 2][i]) % mod + (((dp[i][k - 1] * dp[n - i - 1][k - 1]) % mod) * cc[n - 2][i]) % mod;
     84                     dp[n][k] %= mod;
     85                 }
     86                 else{
     87                     dp[n][k] += ((tmp1 + tmp2) % mod) + (((dp[i][k - 1] * dp[n - i - 1][k - 1]) % mod) * cc[n - 2][i]) % mod;
     88                     dp[n][k] %= mod;
     89                 }
     90             }
     91             dp[n][k] *= n;
     92             dp[n][k] %= mod;
     93             ss[n][k] = ss[n][k - 1] + dp[n][k];
     94         }
     95         for (int k = n + 1; k <= 360; k++){
     96             ss[n][k] = ss[n][k - 1];
     97         }
     98     }
     99     #if debug
    100     for (int i = 0; i < 10; i++){
    101         for (int j = 0; j < 10; j++)
    102             printf("%6I64d ", dp[i][j]);
    103         puts("");
    104     }
    105     for (int i = 0; i < 10; i++){
    106         for (int j = 0; j < 10; j++)
    107             printf("%6I64d ", ss[i][j]);
    108         puts("");
    109     }
    110     #endif
    111 }
    112 /*
    113 ll dfs(int n, int k){
    114     ll ret = 0;
    115     ll tmp1, tmp2;
    116 
    117     if (dp[n][k]) return dp[n][k];
    118     if (!n || k < lg[n] || k > n) return 0;
    119 
    120     for (int i = 0; i <= n - 1; i++){
    121         #if debug
    122         printf("i  %d:\n", i);
    123         #endif
    124         tmp1 = tmp2 = 0;
    125         for (int j = lg[i]; j <= min2(k - 2, i); j++){
    126             tmp1 += dfs(i, j);
    127             tmp1 %= mod;
    128 
    129             //ret += ((dfs(i, j) * dfs(n - i - 1, k - 1)) % mod) * C(n - 2, i);
    130             //ret %= mod;
    131         }
    132         #if debug
    133         printf("%d %d  tmp1: %I64d   %d %d  r: %I64d\n", n, k, tmp1, n - i - 1, k - 1, dfs(n - i - 1, k - 1));
    134         #endif
    135         tmp1 *= dfs(n - i - 1, k - 1);
    136         tmp1 %= mod;
    137         for (int j = lg[n - i - 1]; j <= min2(k - 2, n - i - 1); j++){
    138             tmp2 += dfs(n - i - 1, j);
    139             tmp2 %= mod;
    140 
    141             //ret += ((dfs(i, k - 1) * dfs(n - i - 1, j)) % mod) * C(n - 2, i);
    142             //ret %= mod;
    143         }
    144         #if debug
    145         printf("%d %d  tmp2: %I64d   %d %d  l: %I64d\n", n, k, tmp2, i, k - 1, dfs(i, k - 1));
    146         #endif
    147         tmp2 *= dfs(i, k - 1);
    148         tmp2 %= mod;
    149         #if debug
    150         printf("tmp1 %I64d   tmp2 %I64d   C  %I64d\n", tmp1, tmp2, C(n - 2, i));
    151         #endif
    152         if (i != n - 1){
    153             ret += (((tmp1 + tmp2) % mod) * cc[n - 2][i]) % mod + (((dfs(i, k - 1) * dfs(n - i - 1, k - 1)) % mod) * cc[n - 2][i]) % mod;
    154             ret %= mod;
    155         }
    156         else{
    157             ret += ((tmp1 + tmp2) % mod) % mod + (((dfs(i, k - 1) * dfs(n - i - 1, k - 1)) % mod) * cc[n - 2][i]) % mod;
    158             ret %= mod;
    159         }
    160         #if debug
    161         printf("%d %d  add: %I64d   ret: %I64d \n", n, k, dfs(i, k - 1) * dfs(n - i - 1, k - 1) * C(n - 2, i), ret);
    162         #endif
    163 
    164     }
    165     ret *= n;
    166     ret %= mod;
    167     dp[n][k] = ret;
    168     #if debug
    169     printf("%d  %d : %I64d\n", n, k, ret);
    170     #endif
    171 
    172     return ret;
    173 }
    174 */
    175 int main(){
    176     int a, b;
    177     int i = 1, c;
    178 
    179     get_c();
    180     init();
    181     pre();
    182     //puts("pass");
    183 
    184 
    185     scanf("%d", &c);
    186     while (c-- && ~scanf("%d%d", &a, &b)){
    187         printf("Case #%d: %I64d\n", i, dp[a][b]);
    188         i++;
    189     }
    190 
    191     return 0;
    192 }

     添加1008的代码  hdu 3457

    View Code
     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 void chg(char &a, char &b){
     5     char t = a;
     6 
     7     a = b + 1;
     8     if (a > 'z') a -= 26;
     9     b = t + 1;
    10     if (b > 'z') b -= 26;
    11 }
    12 
    13 bool judge(char *a, char *b){
    14     int l = strlen(a);
    15     int sum = 0;
    16 
    17     if (l == 2){
    18         for (int i = 0; i < 26; i++){
    19             chg(a[0], a[1]);
    20             if (!strcmp(a, b)) return true;
    21         }
    22         return false;
    23     }
    24     for (int i = 0; i < l; i++){
    25         sum += a[i] - b[i];
    26     }
    27     if (sum & 1) return false;
    28     return true;
    29 }
    30 
    31 int main(){
    32     char s1[100], s2[100];
    33     int n;
    34 
    35     scanf("%d", &n);
    36     for (int tt = 1; tt <= n; tt++){
    37         scanf("%s%s", s1, s2);
    38         printf("Case #%d: ", tt);
    39         if (judge(s1, s2)) printf("YES\n");
    40         else printf("NO\n");
    41     }
    42 
    43     return 0;
    44 }

    ——written by Lyon

  • 相关阅读:
    Linux内核TSS的使用
    DPL, CPL及RPL之间的关系
    Linux内存管理(深入理解Linux内核)
    Windows下安装PIL进行图像处理
    内存Zone中的pageset成员分析
    导出符号的意义
    GDI及Windows的消息机制
    kmalloc vs vmalloc
    Linux Kernel Development有关内存管理
    STL sort
  • 原文地址:https://www.cnblogs.com/LyonLys/p/2012MUTC6_Lyon.html
Copyright © 2011-2022 走看看