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。