這篇一早寫好,原打算等競賽結束再貼。可昨天發現網上已到處都有討論及解答,就不再等了。
前些日子玩的一道題,雖然解題失敗,但還是覺得值得記上一筆。題是這樣的
給定乙個字串,僅由a,b,c 3種小寫字母組成。當出現連續兩個不同的字母時,你可以用另外乙個字母替換它,如
- 有ab或ba連續出現,你把它們替換為字母c;
- 有ac或ca連續出現時,你可以把它們替換為字母b;
- 有bc或cb 連續出現時,你可以把它們替換為字母a。
你可以不斷反覆按照這個規則進行替換,你的目標是使得最終結果所得到的字串盡可能短,求最終結果的最短長度。
輸入:字串。長度不超過200,僅由abc三種小寫字母組成。
輸出:按照上述規則不斷消除替換,所得到的字串最短的長度。
例如:輸入cab,輸出2。因為我們可以把它變為bb或者變為cc。
輸入bcab,輸出1。儘管我們可以把它變為aab -> ac -> b,也可以把它變為bbb,但因為前者長度更短,所以輸出1。
我對純粹的數學公式推導還是很怕的。年紀越大,越偏文了?但這道題比起公式推導,推理的味道更濃些。
失敗的原因是超時。似乎應該先讀題,分析及做好準備後,再去答題。我直接點了進去,在倒計時的恫嚇下,兩個小時裡啥都沒乾成...
挑戰失敗後,反倒靜下心來。最先找到的規律就是重複的字母可以化簡,比如三個a和乙個a是等價的,4個b和2個b也是等價的。於是直接開寫實現這個化簡邏輯的**。m大人也被我拖下水,途中參戰。不愧是m大人,思路很直接:「每次消除時都能保證最短即可!」先找感覺再找理論支撐是m大人的風格。結果證明這個思路也是對的!一發命中也是m大人的風格!
我這時卻陷入了困境——即便整理好重複的字元,依然a啊b啊c的團團混雜,看不出個所以然。在我打算放棄,m大人的一句話點亮了我的解題道路——雖然她自己不大在意——「c其實等價於ab!」。是的,如果c等價於ab,那麼把c用ab(或ba)替換掉後,字串就只剩下ab了,就又可以整理重複的字元了!哇哈哈!到這裡才發現,原來我的思路就只是「整理」!」
這回學乖了,不寫**了,先觀察分析——總是忘記這條多年來學到寶貴經驗。我發現如果相同的奇數個字元無論多少個都會產生同樣結果,偶數也同樣。這樣可以進一步化簡,所有重複的奇數字元都算作乙個,所有偶數的都算作兩個。字串最終化簡成axbxax... x可能是1或2。到這裡規律很容易找到:
c替換成ab;統計ab的個數;當a和b的個數都是偶數時,結果是兩個;否則是乙個。
m大人最終的邏輯則複雜些:
遍歷字串;嘗試消除字元;不能消除則繼續;如能消除,用再前一位和再後一位字元評價是否能保證最短(=即不同),能則消,否則繼續;一旦有消除發生,重新遍歷消除後的新字串;遍歷結束時檢查是否存在可以消除但卻沒通過評價的情況,如果有則消除,重新遍歷。
上面的邏輯再加上,如果該字串全部字元相同——比如都是a——這樣的特殊情況就全活了!
這裡的論證不是那麼嚴謹,但是結果我覺得是相當的...理想。
**如下:
public class erasechar ;
public static void main(string args)
strings.add("a");
strings.add("b");
strings.add("c");
strings.add("ab");
strings.add("abc");
strings.add("aa");
strings.add("aaa");
strings.add("aaaa");
strings.add("cacccc");
// end === 測試資料。
for (string s : strings) ");
if (min1 != min2) }}
/*** c替換成ab;統計ab的個數;當a和b的個數都是偶數時,結果是兩個;否則是乙個。
* @param s
* @return
*/public static int gg(string s)
int counta = 0;
int countb = 0;
for (char c : chars)
}if (counta % 2 == 0 && countb % 2 == 0)
return 1;
}public static int mm(string s)
linkedlistlist = new linkedlist<>();
for (char c : chars)
return getmimi(list);
}/**
* * 嘗試消除字元;
* 如不能消除則繼續;
* 如能消除,用再前一位和再後一位字元評價是否能保證最短(=即不同),能則消,否則繼續;
* 一旦有消除發生,重新遍歷消除後的新字串;
* 遍歷結束時檢查是否存在可以消除但卻沒通過評價的情況,如果有則消除,重新遍歷。
*
字串消除
給定乙個字串,僅由a,b,c 3種小寫字母組成。當出現連續兩個不同的字母時,你可以用另外乙個字母替換它,如 有ab或ba連續出現,你把它們替換為字母c 有ac或ca連續出現時,你可以把它們替換為字母b 有bc或cb 連續出現時,你可以把它們替換為字母a。你可以不斷反覆按照這個規則進行替換,你的目標是...
字串消除
題目詳情 給定乙個字串,僅由a,b,c 3種小寫字母組成。當出現連續兩個不同的字母時,你可以用另外乙個字母替換它,如 有ab或ba連續出現,你把它們替換為字母c 有ac或ca連續出現時,你可以把它們替換為字母b 有bc或cb 連續出現時,你可以把它們替換為字母a。你可以不斷反覆按照這個規則進行替換,...
字串消除
小hi最近在玩乙個字元消除遊戲。給定乙個只包含大寫字母 abc 的字串s,消除過程是如下進行的 1 如果s包含長度超過1的由相同字母組成的子串,那麼這些子串會被同時消除,餘下的子串拼成新的字串。例如 abccbcccaa 中 cc ccc 和 aa 會被同時消除,餘下 ab 和 b 拼成新的字串 a...