• 2018年青岛站


     题目链接:http://acm.zju.edu.cn/onlinejudge/showContestProblems.do?contestId=381

    C题:

    题意:

      有长度为n的两个串s和t,你可以翻转两次子串(1->0,0->1),问有多种方案能使得s和t相等。

    思路:

      1.对于初始时s==t有任取一个区间,将其翻转两次即可,此时方案数为n + n * (n - 1) / 2 = n * (n + 1) / 2;

      2.对于s和t有一个区间不同时,设这个区间为tt,则此时只需寻找一个大串ss包含tt,将ss串翻转一次,再将ss-tt翻转(顺序颠倒为另一方案)即可,设tt前面还有k1个字符,后面还有k2个字符,则此时方案数为(|tt| - 1)* 2 + 2 * k1 + 2 * k2;

      3.对于s和t有两个区间不同时,此时方案数固定为6:

        a.将第一个串翻转,第二个串翻转,顺序颠倒为另一种方案;

        b.第一个串及第一二个串中间的那段一起翻转,第二个串及第一二个串中间的那段一起翻转,顺序颠倒为另一种方案;

        c.第一个串及第一二个串中间那段以及第二个串进行翻转,将中间那段翻转,顺序颠倒为另一种方案。

      4.对于s和t不同的区间数大于2的,此时方案数为0。

    代码实现如下:

     1 #include <set>
     2 #include <map>
     3 #include <queue>
     4 #include <stack>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <bitset>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 using namespace std;
    16 
    17 typedef long long LL;
    18 typedef pair<LL, LL> pLL;
    19 typedef pair<LL, int> pli;
    20 typedef pair<int, LL> pil;;
    21 typedef pair<int, int> pii;
    22 typedef unsigned long long uLL;
    23 
    24 #define lson rt<<1
    25 #define rson rt<<1|1
    26 #define lowbit(x) x&(-x)
    27 #define  name2str(name) (#name)
    28 #define bug printf("*********
    ")
    29 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    30 #define FIN freopen("D://code//in.txt", "r", stdin)
    31 #define IO ios::sync_with_stdio(false),cin.tie(0)
    32 
    33 const double eps = 1e-8;
    34 const int mod = 1000000007;
    35 const int maxn = 1e6 + 7;
    36 const double pi = acos(-1);
    37 const int inf = 0x3f3f3f3f;
    38 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    39 
    40 int T, n;
    41 char s[maxn], t[maxn];
    42 pLL st[maxn];
    43 
    44 int main() {
    45 #ifndef ONLINE_JUDGE
    46     FIN;
    47 #endif
    48     scanf("%d", &T);
    49     while(T--) {
    50         scanf("%d", &n);
    51         scanf("%s%s", s + 1, t + 1);
    52         int cnt = 0, flag = 0;
    53         for(int i = 1; i <= n; i++) {
    54             if(s[i] != t[i] && !flag) {
    55                 st[cnt].first = i;
    56                 flag = 1;
    57             } else if(s[i] == t[i] && flag) {
    58                 st[cnt++].second = i;
    59                 flag = 0;
    60             }
    61         }
    62         if(flag) st[cnt++].second = n;
    63         if(cnt == 0) printf("%lld
    ", 1LL * n * (n + 1) / 2);
    64         else if(cnt == 1) {
    65             printf("%lld
    ", 2 * (st[0].second - st[0].first) + 2 * (st[0].first - 1) + 2 * (n - st[0].second));
    66         } else if(cnt == 2) {
    67             printf("6
    ");
    68         } else {
    69             printf("0
    ");
    70         }
    71     }
    72     return 0;
    73 }

    E题:

    题意:

      题目背景为植物大战僵尸。

      你拥有n棵植物,每棵植物坐标为i(i=0,1,2……)的初始防御值均为0,成长值为ai。

      坐标0出有一辆浇水的车,该车只允许向左向右移动一格,移动到某个坐标i时就会对i上的植物进行浇水,使其防御值增长ai。

      花园的防御值的定义为所有植物的防御值的最小值。

      问花园的防御值的最大值为多少。

    思路:

      一眼二分,二分花园的防御值为x,则该题等价于固定x,求使得所有植物的防御值di大于等于x的浇水车的最小移动步数。

      易知只有当这辆车在相邻两棵植物(x,x+1)间反复移动直至左边那颗植物的防御值大于等于x才转移到x+1与x+2间反复移动时浇水车的移动步数最优。

      不过对于最右端的n-1和n要特别分析,最后车子可以停留在n-1而不停留在n处。

    代码实现如下:

      1 #include <set>
      2 #include <map>
      3 #include <queue>
      4 #include <stack>
      5 #include <cmath>
      6 #include <ctime>
      7 #include <bitset>
      8 #include <cstdio>
      9 #include <string>
     10 #include <vector>
     11 #include <cstdlib>
     12 #include <cstring>
     13 #include <iostream>
     14 #include <algorithm>
     15 using namespace std;
     16 
     17 typedef long long LL;
     18 typedef pair<LL, LL> pLL;
     19 typedef pair<LL, int> pli;
     20 typedef pair<int, LL> pil;;
     21 typedef pair<int, int> pii;
     22 typedef unsigned long long uLL;
     23 
     24 #define lson rt<<1
     25 #define rson rt<<1|1
     26 #define lowbit(x) x&(-x)
     27 #define  name2str(name) (#name)
     28 #define bug printf("*********
    ")
     29 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
     30 #define FIN freopen("D://code//in.txt", "r", stdin)
     31 #define IO ios::sync_with_stdio(false),cin.tie(0)
     32 
     33 const double eps = 1e-8;
     34 const int mod = 1000000007;
     35 const int maxn = 1e5 + 7;
     36 const double pi = acos(-1);
     37 const int inf = 0x3f3f3f3f;
     38 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
     39 
     40 int t, n;
     41 LL m;
     42 int a[maxn];
     43 LL num[maxn];
     44 
     45 bool check(LL x) {
     46     for(int i = 1; i <= n; i++) {
     47         num[i] = (x + a[i] - 1) / a[i];
     48     }
     49     LL cnt = 0;
     50     for(int i = 1; i < n - 1; i++) {
     51         cnt ++;
     52         num[i]--;
     53         if(cnt > m) return false;
     54         if(num[i] > 0) {
     55             cnt += 2 * num[i];
     56             if(cnt > m) return false;
     57             if(num[i+1] > 0) {
     58                 num[i+1] -= num[i];
     59             }
     60             num[i] = 0;
     61         }
     62     }
     63     num[n-1]--;
     64     cnt++;
     65     if(num[n-1] > 0) {
     66         cnt += 2 * num[n-1];
     67         if(cnt > m) return false;
     68         num[n] -= num[n-1];
     69     }
     70     if(num[n] > 0) {
     71         num[n]--;
     72         cnt++;
     73         cnt += 2 * num[n];
     74     }
     75     return cnt <= m;
     76 }
     77 
     78 int main() {
     79 #ifndef ONLINE_JUDGE
     80     FIN;
     81 #endif
     82     scanf("%d", &t);
     83     while(t--) {
     84         scanf("%d%lld", &n, &m);
     85         for(int i = 1; i <= n;  i++) {
     86             scanf("%d",  &a[i]);
     87         }
     88         if(m < n) {
     89             printf("0
    ");
     90             continue;
     91         }
     92         LL ub = INF, lb = 0, mid, ans;
     93         while(ub >= lb) {
     94             mid = (ub + lb) >> 1;
     95             if(check(mid)) {
     96                 ans = mid;
     97                 lb = mid + 1;
     98             } else {
     99                 ub = mid - 1;
    100             }
    101         }
    102         printf("%lld
    ", ans);
    103     }
    104     return 0;
    105 }

    J题:

    题意:

      初始时主人公带着x元钱去书店买m本书,他的买书规则如下:

        1.书按照1至n排成一排进行编号;

        2.如果主人公身上目前拥有的钱大于等于书的价格则一定会买这本书,且主人公拥有的钱减少书的价格;

        3.如果主人公的钱少于书的价格则跳过该书。

      求主人公初始拥有的钱x的最大值(如果无法估计则输出Richhman,如果不能恰好购买m本书则输出Impossible)。

    思路:

      对于本题由于买书规则的特殊,我们可以分析当n==m时此时主人公初始的钱是无法估计的,当书的价格为0的书的数量大于m时时Impossible。

      对于其他情况则需记录书的价格为0的书的数量,记为num,最后一本价格为0的书的位置为pos。

      1.如果pos<=m,则直接x=前m本书的价格+min(后面n-m本书的价格)- 1;

      2.如果pos>m,则购买m-num本非0的书,然后+min(其他非0书的价格) - 1。

    代码实现如下:

     1 #include <set>
     2 #include <map>
     3 #include <queue>
     4 #include <stack>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <bitset>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 using namespace std;
    16 
    17 typedef long long LL;
    18 typedef pair<LL, LL> pLL;
    19 typedef pair<LL, int> pli;
    20 typedef pair<int, LL> pil;;
    21 typedef pair<int, int> pii;
    22 typedef unsigned long long uLL;
    23 
    24 #define lson rt<<1
    25 #define rson rt<<1|1
    26 #define lowbit(x) x&(-x)
    27 #define  name2str(name) (#name)
    28 #define bug printf("*********
    ")
    29 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    30 #define FIN freopen("D://code//in.txt", "r", stdin)
    31 #define IO ios::sync_with_stdio(false),cin.tie(0)
    32 
    33 const double eps = 1e-8;
    34 const int mod = 1000000007;
    35 const int maxn = 1e5 + 7;
    36 const double pi = acos(-1);
    37 const int inf = 0x3f3f3f3f;
    38 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    39 
    40 int t, n, m;
    41 int a[maxn];
    42 
    43 int main() {
    44 #ifndef ONLINE_JUDGE
    45     FIN;
    46 #endif
    47     scanf("%d", &t);
    48     while(t--) {
    49         scanf("%d%d", &n, &m);
    50         int num = 0, pos = -1;
    51         LL ans = 0;
    52         int mx = inf, mx2 = inf;
    53         for(int i = 0; i < n; i++) {
    54             scanf("%d", &a[i]);
    55             mx = min(mx, a[i]);
    56             if(!a[i]) {
    57                 num++;
    58                 pos = i;
    59             }
    60             if(i < m) ans += a[i];
    61             else {
    62                 mx2 = min(mx2, a[i]);
    63             }
    64         }
    65         if(n == m) {
    66             printf("Richman
    ");
    67         } else {
    68             if(num > m) {
    69                 printf("Impossible
    ");
    70             } else {
    71                 if(m == 0) {
    72                     printf("%d
    ", mx - 1);
    73                 } else {
    74                     if(pos >= m) {
    75                         m -= num;
    76                         int tmp = 0;
    77                         mx2 = inf, ans = 0;
    78                         for(int i = 0; i < n; i++) {
    79                             if(a[i] && tmp < m) {
    80                                 ans += a[i];
    81                                 tmp++;
    82                             } else if(a[i]) {
    83                                 mx2 = min(mx2, a[i]);
    84                             }
    85                         }
    86                     }
    87                     printf("%lld
    ", ans + mx2 - 1);
    88                 }
    89             }
    90         }
    91     }
    92     return 0;
    93 }

     M题:

    题意:

      给你每个数对应的权值。

      定义f(x)=x的每一位上的数字对应的权值之和。

      定义g[0][x]=x,g[k][x]=f(g[k-1][x]),k>=1。

      求g[k][x]。

    思路:

      经冷静分析我们可以发现当k大于等于2(打表可以发现,不过由于我只打了前几千的值,可能这个数应该要大于2,但是绝对非常小)时其实就是0和1的循环,因此我们对于前面的值进行暴力,出现0时就直接break掉,并记录此时对应的是第多少位上(记为pos),如果k<=pos,那么就直接输出,否则如果k%2==pos%2,则输出0,否则输出1。

    代码实现如下:

     1 #include <set>
     2 #include <map>
     3 #include <queue>
     4 #include <stack>
     5 #include <cmath>
     6 #include <ctime>
     7 #include <bitset>
     8 #include <cstdio>
     9 #include <string>
    10 #include <vector>
    11 #include <cstdlib>
    12 #include <cstring>
    13 #include <iostream>
    14 #include <algorithm>
    15 using namespace std;
    16 
    17 typedef long long LL;
    18 typedef pair<LL, LL> pLL;
    19 typedef pair<LL, int> pli;
    20 typedef pair<int, LL> pil;;
    21 typedef pair<int, int> pii;
    22 typedef unsigned long long uLL;
    23 
    24 #define lson rt<<1
    25 #define rson rt<<1|1
    26 #define lowbit(x) x&(-x)
    27 #define  name2str(name) (#name)
    28 #define bug printf("*********
    ")
    29 #define debug(x) cout<<#x"=["<<x<<"]" <<endl
    30 #define FIN freopen("D://code//in.txt", "r", stdin)
    31 #define IO ios::sync_with_stdio(false),cin.tie(0)
    32 
    33 const double eps = 1e-8;
    34 const int mod = 1000000007;
    35 const int maxn = 30000000 + 7;
    36 const double pi = acos(-1);
    37 const int inf = 0x3f3f3f3f;
    38 const LL INF = 0x3f3f3f3f3f3f3f3fLL;
    39 
    40 int t, x, k;
    41 int a[20], num[] = {1, 0, 0, 0, 1, 0, 1, 0, 2, 1};
    42 
    43 int main() {
    44     scanf("%d", &t);
    45     while(t--) {
    46         scanf("%d%d", &x, &k);
    47         if(k == 0) {
    48             printf("%d
    ", x);
    49             continue;
    50         }
    51         int pos = -1, cnt = 0;
    52         if(x == 0) a[cnt++] = 0;
    53         while(x) {
    54             a[cnt++] = x % 10;
    55             x /= 10;
    56         }
    57         for(int i = 1; i <= k; i++) {
    58             x = 0;
    59             for(int i = 0; i < cnt; i++) {
    60                 x += num[a[i]];
    61             }
    62             //debug(x);
    63             if(x == 0) {
    64                 pos = i;
    65                 break;
    66             } else if(i == k) {
    67                 printf("%d
    ", x);
    68             }
    69             cnt = 0;
    70             while(x) {
    71                 a[cnt++] = x % 10;
    72                 x /= 10;
    73             }
    74         }
    75         //debug(pos);
    76         if(pos != -1) {
    77             if(k % 2 == pos % 2) {
    78                 printf("0
    ");
    79             } else {
    80                 printf("1
    ");
    81             }
    82         }
    83     }
    84     return 0;
    85 }
  • 相关阅读:
    [转]实习生需要懂的40大基本规矩
    [转]Linux下pppoe配合Drcom插件上网方法介绍......
    收藏一些图书
    [转]30个自我提升技巧
    [转]关于Gmail打不开的解决办法
    [转]李开复经典语录盘点:人生之路在于每次的选择
    [转]哈佛管理世界中智慧
    胡伟武校友在2011年中国科大本科生毕业典礼暨学位授予仪式上的讲话
    Dynamics4.0和Dynamics2011处理Email的方法
    JS实现简单的ToolTip功能
  • 原文地址:https://www.cnblogs.com/Dillonh/p/9910371.html
Copyright © 2020-2023  润新知