1. 程式人生 > >2018CHD-ACM新生賽(正式賽)D.刀塔大師lwq I

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。