字串消除

2021-09-01 19:43:00 字數 2526 閱讀 4534

這篇一早寫好,原打算等競賽結束再貼。可昨天發現網上已到處都有討論及解答,就不再等了。

前些日子玩的一道題,雖然解題失敗,但還是覺得值得記上一筆。題是這樣的

給定乙個字串,僅由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...