• 2018CHD-ACM新生赛(正式赛)D.刀塔大师lwq I


    Description
    作为彩虹岛的刀塔大师,lwq很擅长操作中单英雄卡尔。卡尔一共拥有10个技能。在卡尔的10个技能当 中,lwq最擅长的就是“幽灵漫步”。下面,lwq想就切技能的问题考考你: lwq共有QWE三种技能球。假设lwq现在的技能状态是QQW,他每次操作可以弹出第一个球,并在最 后插入一个球。例如lwq现在可以从状态QQW,经过一次操作后变成QWQ,QWW或者QWE。现在lwq给 出了他的初始技能状态和目标技能状态,想让你求出他的最少操作次数。(初始技能状态和目标技能状态恒 为3个球。QWE和WEQ视为同一种状态,即对应技能球数目相同则视为同一状态,位置不用相同。)

    Input

    输入第一行为一个整数T(T ≤ 60),表示一共有T组测试数据。 对于每组测试数据: 第一行有三个字符a,b,c(a,b,c ∈{Q,W,E}),表示初始技能状态。 第二行有三个字符d,e,f(d,e,f ∈{Q,W,E}),表示目标技能状态。

    Output
    对于每组测试数据输出一个整数x,表示从初始技能状态到目标技能状态的最少操作次数。

    Sample Input
    2

    QWE

    EEE

    WQE

    EWQ

    Sample Output
    2

    0

    Hint
    对于第一组样例,第一次操作弹出球Q插入球E,第二次操作弹出球W插入球E。 对于第二组样例,初始技能状态和目标技能状态相同,无需操作。

    思路:由于初始到目标的操作为从前往后弹出,所以对初始状态从右往左判断,用vis数组保存目标状态的三种技能的个数,扫描初始状态时,将vis数组中对应的单元减一,表示不需要对该技能操作一次,因为技能数不能为负,故若减到-1就跳出,最后求总操作数。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #define M 1000005
     7 
     8 using namespace std;
     9 char a[M], b[M];
    10 int main()
    11 {
    12     int t;
    13     cin >> t;
    14     while (t--)
    15     {
    16         int vis[3];
    17         memset(vis, 0, 3 * sizeof(int));
    18         for (int i = 0; i < 3; i++) cin >> a[i];
    19         for (int i = 0; i < 3; i++)
    20         {
    21             cin >> b[i];
    22             if (b[i] == 'Q') vis[0]++;  //vis[0]记录Q的个数,如下同理
    23             if (b[i] == 'W') vis[1]++;
    24             if (b[i] == 'E') vis[2]++;
    25         }
    26 
    27         for (int i = 2; i >= 0; i--)  //对初始状态从右往左扫
    28         {
    29             if (a[i] == 'Q')
    30             {
    31                 vis[0]--;
    32                 if (vis[0] == -1)
    33                 {
    34                     vis[0] += 1;  //若减到-1,重置为0,否则最后求和时会出问题
    35                     break;
    36                 }
    37             }
    38             if (a[i] == 'W')
    39             {
    40                 vis[1]--;
    41                 if (vis[1] == -1)
    42                 {
    43                     vis[1] += 1;
    44                     break;
    45                 }
    46             }
    47             if (a[i] == 'E')
    48             {
    49                 vis[2]--;
    50                 if (vis[2] == -1)
    51                 {
    52                     vis[2] += 1;
    53                     break;
    54                 }
    55             }
    56         }
    57 
    58         int sum = 0;
    59         for (int i = 0; i < 3; i++)
    60         {
    61             sum += vis[i];
    62         }
    63         cout << sum << endl;
    64     }
    65     return 0;
    66 }

    备注:一开始并没有注意到跳出循环前要对-1重置,觉得最后求和时只要对结果+1即可,但是这种方法会混淆0 0 0和0 -1 0这样的数据,前者相等,操作数为0,后者不相等,操作数为1。

    ————————————————
    心里有光,哪儿都美
  • 相关阅读:
    leetcode(c++)(扫描线)
    深度学习手撕系列整理(待完善)
    leetcode(c++)(单调序列)
    leetcode(c++)(滑动窗口)
    leetcode(c++)(前缀和)
    【数据结构之字典树Trie】C语言实现
    微信小程序页面跳转如何传递对象参数
    动态规划
    数据结构(五)图图的两种遍历(深度优先和广度优先)
    红黑树(RebBlackTree)
  • 原文地址:https://www.cnblogs.com/harutomimori/p/10105843.html
Copyright © 2020-2023  润新知