• 2016 ACM/ICPC亚洲区青岛站现场赛(部分题解)


    摘要

      本文主要列举并求解了2016 ACM/ICPC亚洲区青岛站现场赛的部分真题,着重介绍了各个题目的解题思路,结合详细的AC代码,意在熟悉青岛赛区的出题策略,以备战2018青岛站现场赛。


    HDU 5984 Pocky

    题意

      给出一根棒子(可以吃的)的长度x和切割过程中不能小于的长度d,每次随机的选取一个位置切开,吃掉左边的一半,对右边的棒子同样操作,直至剩余的长度不大于d时停止。现在给出x和d,问切割次数的数学期望是多少。

    解题思路

      当看到第二个样例2 1时,结果是1.693147,联想到ln(2) = 0.693147,可猜测当x > d时,答案是ln(x/d) + 1。

    详细解法:

      设长度为x、限制长度是d的棒切割次数的数学期望是f(x),首先当x < d时,f(x) = 0(直接结束,切割次数为0);当x >= d时,f(x) 应该是任选一点后,右边部分切割次数的数学期望加上1。设t是切割的位置,即,其中后面的式子表示切割点t的数学期望(积分0到x,取到这一点的概率乘上t的概率密度,也就是长度为t的切割次数的数学期望),进而又可以写成(积分中,系数可以自由进出),也即将f(x)写成如下形式

       由此可得f(x) = ln(x) + c,当x = d时,f(d) = ln(d) + c = 1得,c = 1 - ln(d),代入f(x) = ln(x) - ln(d) + 1,也即f(x) = ln(x/d) + 1;

    综上所述

    代码如下:

      其中涉及C语言中对数的表示方法,C中只定义两log(double x)和log10(double x),分别表示数学中的ln和lg,至于如何表示loga(b)呢?使用换底公式log(b)/log(a)即可。

     1 #include <cstdio>
     2 #include <cmath>
     3 
     4 int main()
     5 {
     6     double x, d;
     7     int T;
     8     scanf("%d", &T);
     9     while(T--) {
    10         scanf("%lf%lf", &x, &d);
    11         if(x <= d) 
    12             printf("0.000000
    ");
    13         else
    14             printf("%.6lf
    ", log(x) - log(d) + 1);
    15     }
    16     return 0;
    17 }

     HDU 5983 Pocket Cube

    题意

      输入一个二阶魔方的状态,问能否一步将其复原。

    解题思路

      需要细心和耐心,考虑每一种拧法,操作的时候,先顺时针改变一个面的数,然后改变四周的数,写出操作模板。要特别注意输入状态的次序,哪个面先,以及哪个角先。

    代码如下:

      1 #include <cstdio>
      2 
      3 struct Magic2{
      4     int f[5], b[5], u[5], d[5], l[5], r[5];
      5     void get_u() {for(int i = 1 ; i <= 4; i++) {scanf("%d", &u[i]);}}
      6     void get_d() {for(int i = 1 ; i <= 4; i++) {scanf("%d", &d[i]);}}
      7     void get_f() {for(int i = 1 ; i <= 4; i++) {scanf("%d", &f[i]);}}
      8     void get_b() {for(int i = 1 ; i <= 4; i++) {scanf("%d", &b[i]);}}
      9     void get_l() {for(int i = 1 ; i <= 4; i++) {scanf("%d", &l[i]);}}
     10     void get_r() {for(int i = 1 ; i <= 4; i++) {scanf("%d", &r[i]);}}
     11     void L(int cnt) {
     12         for(; cnt > 0; cnt--) {
     13             int a[5];
     14             for(int i = 1; i <= 4; i++) a[i] = l[i];
     15             l[2] = a[1];l[1] = a[3];
     16             l[3] = a[4];l[4] = a[2];
     17 
     18             int x = b[3], y = b[1];
     19             b[3] = d[3], b[1] = d[1];
     20             d[3] = f[3], d[1] = f[1];
     21             f[3] = u[3], f[1] = u[1];
     22             u[3] = x, u[1] = y;
     23         }
     24     }
     25     void R(int cnt) {
     26         for(; cnt > 0; cnt--) {
     27             int a[5];
     28             for(int i = 1; i <= 4; i++) a[i] = r[i];
     29             r[1] = a[3], r[2] = a[1];
     30             r[3] = a[4], r[4] = a[2];
     31 
     32             int x = b[2], y = b[4];
     33             b[2] = u[2], b[4] = u[4];
     34             u[2] = f[2], u[4] = f[4];
     35             f[2] = d[2], f[4] = d[4];
     36             d[2] = x, d[4] = y;
     37         }
     38     }
     39     void U(int cnt) {
     40             for(; cnt > 0; cnt--) {
     41             int a[5];
     42             for(int i = 1; i <= 4; i++) a[i] = u[i];
     43             u[1] = a[3], u[2] = a[1];
     44             u[3] = a[4], u[4] = a[2];
     45 
     46             int x = b[3], y = b[4];
     47             b[3] = l[4], b[4] = l[2];
     48             l[4] = f[2], l[2] = f[1];
     49             f[2] = r[1], f[1] = r[3];
     50             r[1] = x, r[3] = y;
     51         }
     52     }
     53     void D(int cnt) {
     54         for(; cnt > 0; cnt--) {
     55             int a[5];
     56             for(int i = 1; i <= 4; i++) a[i] = d[i];
     57             d[2] = a[1], d[1] = a[3];
     58             d[4] = a[2], d[3] = a[4];
     59 
     60             int x = b[1], y = b[2];
     61             b[1] = r[4], b[2] = r[2];
     62             r[4] = f[3], r[2] = f[4];
     63             f[3] = l[1], f[4] = l[3];
     64             l[1] = x, l[3] = y;
     65         }
     66     }
     67     void F(int cnt) {
     68         for(; cnt > 0; cnt--) {
     69             int a[5];
     70             for(int i = 1; i <= 4; i++) a[i] = f[i];
     71             f[1] = a[3], f[2] = a[1];
     72             f[3] = a[4], f[4] = a[2];
     73 
     74             int x = u[3], y = u[4];
     75             u[3] = l[3], u[4] = l[4];
     76             l[3] = d[1], l[4] = d[2];
     77             d[1] = r[3], d[2] = r[4];
     78             r[3] = x, r[4] = y;
     79         }
     80     }
     81     void B(int cnt) {
     82         for(; cnt > 0; cnt--) {
     83             int a[5];
     84             for(int i = 1; i <= 4; i++) a[i] = u[i];
     85             u[1] = a[3], u[3] = a[4];
     86             u[2] = a[1], u[4] = a[2];
     87 
     88             int x = u[1], y = u[2];
     89             u[1] = r[1], u[2] = r[2];
     90             r[1] = d[4], r[2] = d[3];
     91             d[4] = l[1], d[3] = l[2];
     92             l[1] = x, l[2] = y;
     93         }
     94     }
     95     bool ok() {
     96         for(int i = 2; i <= 4; i++) {
     97             if(u[i] != u[1] || d[i] != d[1]
     98             || l[i] != l[1] || r[i] != r[1]
     99             || f[i] != f[1] || b[i] != b[1])
    100                 return 0;
    101         }
    102         return 1;
    103     }
    104     bool operate(char ch) {
    105         if(ch == 'u') {
    106             U(1);
    107             if(ok())
    108                 return 1;
    109             else {
    110                 U(3);
    111                 U(3);
    112                 if(ok())
    113                     return 1;
    114                 else{
    115                     U(1);
    116                     return 0;
    117                 }
    118             }
    119         }
    120         if(ch == 'd') {
    121             D(1);
    122             if(ok())
    123                 return 1;
    124             else{
    125                 D(3);
    126                 D(3);
    127                 if(ok())
    128                     return 1;
    129                 else{
    130                     D(1);
    131                     return 0;
    132                 }
    133             }
    134         }
    135         if(ch == 'f') {
    136             F(1);
    137             if(ok())
    138                 return 1;
    139             else{
    140                 F(3);
    141                 F(3);
    142                 if(ok())
    143                     return 1;
    144                 else{
    145                     F(1);
    146                     return 0;
    147                 }
    148             }
    149         }
    150         if(ch == 'b') {
    151             B(1);
    152             if(ok())
    153                 return 1;
    154             else{
    155                 B(3);
    156                 B(3);
    157                 if(ok())
    158                     return 1;
    159                 else{
    160                     B(1);
    161                     return 0;
    162                 }
    163             }
    164         }
    165         if(ch == 'l') {
    166             L(1);
    167             if(ok())
    168                 return 1;
    169             else{
    170                 L(3);
    171                 L(3);
    172                 if(ok())
    173                     return 1;
    174                 else{
    175                     L(1);
    176                     return 0;
    177                 }
    178             }
    179         }
    180         if(ch == 'r') {
    181             R(1);
    182             if(ok())
    183                 return 1;
    184             else{
    185                 R(3);
    186                 R(3);
    187                 if(ok())
    188                     return 1;
    189                 else{
    190                     R(1);
    191                     return 0;
    192                 }
    193             }
    194         }
    195     }
    196     void print() {
    197         puts("###");
    198         for(int i = 1; i <= 4; i++) printf("%d ", u[i]); puts("");
    199         for(int i = 1; i <= 4; i++) printf("%d ", f[i]); puts("");
    200         for(int i = 1; i <= 4; i++) printf("%d ", d[i]); puts("");
    201         for(int i = 1; i <= 4; i++) printf("%d ", b[i]); puts("");
    202         for(int i = 1; i <= 4; i++) printf("%d ", l[i]); puts("");
    203         for(int i = 1; i <= 4; i++) printf("%d ", r[i]); puts("");
    204     }
    205 }m2;
    206 
    207 int main()
    208 {
    209     int T;
    210     scanf("%d", &T);
    211     while(T--) {
    212         m2.get_u();
    213         m2.get_f();
    214         m2.get_d();
    215         m2.get_b();
    216         m2.get_l();
    217         m2.get_r();
    218         if(m2.ok() || m2.operate('u') || m2.operate('d') || m2.operate('l')
    219         || m2.operate('r') || m2.operate('f') || m2.operate('b'))
    220             printf("YES
    ");
    221         else
    222             printf("NO
    ");
    223     }
    224     return 0;
    225 }

    HDU 5985 Lucky Coins

    题意

      给出n个硬币和每个硬币的数量和正面朝上的概率,问每个硬币成为幸运硬币的概率是多少。成为幸运硬币的条件是每投一次将所有背面朝上的硬币去掉,继续抛掷,直至剩下一种或者一个都剩下,那最后一种留下的硬币就是幸运硬币。

    解题思路

      概率DP,我们定义dead[i][j]表示第i种硬币在前j步以内全部被抛弃的概率,显然

    化简可得 .

      那么我们定义aliv[i][j] 表示第i种硬币在前j步以内至少有一个没有被抛弃的概率是 1 - dead[i][j],那么第i个硬币成为幸运硬币的概率大概等于(应为当k = 30的时候0.5的三十次方就很小),其实际意义就是第i种硬币成为幸运硬币的概率等于模拟投掷100次,而每次让第1到n种硬币在k步全部被抛弃的概率乘上第i种硬币在第k步至少还有一个而第k+1步全部被抛弃的概率,当然前面的第1到第n种硬币全部被抛弃不包括第i种硬币,故完整的式子是:

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <cstring>
     5 
     6 using namespace std;
     7 
     8 const int maxn = 15;
     9 int n;
    10 double num[maxn], p[maxn], ans[maxn];
    11 double dead[maxn][110], alive[maxn][110];
    12 
    13 void cdead() {
    14     for(int k = 1; k <= 100; k++) {
    15         for(int i = 0; i < n; i++) {
    16             dead[i][k] = pow(1.0 - pow(p[i], k), num[i]);
    17         }
    18     }
    19 }
    20 void calive() {
    21     for(int k = 1; k <= 100; k++) {
    22         for(int i = 0; i < n; i++) {
    23             alive[i][k] = 1.0 - dead[i][k];
    24         }
    25     }
    26 }
    27 
    28 int main()
    29 {
    30     int T;
    31     scanf("%d", &T);
    32     while(T--) {
    33         scanf("%d", &n);
    34         for(int i = 0; i < n; i++) {
    35             scanf("%lf%lf", &num[i], &p[i]);
    36         }
    37         if(n == 1) {
    38             printf("1.000000
    ");
    39             continue;
    40         }
    41 
    42         cdead();
    43         calive();
    44         memset(ans, 0, sizeof(ans));
    45         for(int k = 1; k <= 100; k++) {
    46             for(int i = 0; i < n; i++) {
    47                 double tmp = 1;
    48                 for(int j = 0; j < n; j++) {
    49                     if(j == i)  continue;
    50                     tmp *= dead[j][k];
    51                 }
    52                 ans[i] += tmp * (alive[i][k] - alive[i][k + 1]);
    53             }
    54         }
    55 
    56         for(int i = 0; i < n; i++) {
    57             printf("%.6lf%c", ans[i], i == n - 1 ? '
    ' : ' ');
    58         }
    59     }
    60     return 0;
    61 }

       可以看出青岛站的题目还是有难度的,主要侧重的是数学推理,准备时应该多以数学推理为主,大战在即,加油!

  • 相关阅读:
    opencv学习记录之霍夫变换
    opencv学习记录之模板匹配
    opencv之傅里叶变换
    opencv学习记录之图像金字塔
    opencv学习记录之图像梯度
    opencv学习记录之形态学操作
    opencv学习记录之腐蚀和膨胀
    使用Python解析豆瓣上Json格式数据
    互联网之子--亚伦.斯沃茨
    Json技术使用代码示例
  • 原文地址:https://www.cnblogs.com/wenzhixin/p/9854395.html
Copyright © 2020-2023  润新知