侧边栏

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。

posted @ 2018-12-11 22:45  晴人  阅读(373)  评论(0编辑  收藏  举报