依舊是龐果網上的一道題目,詳情如下:
給定一個字符串,僅由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。
函數頭部: C/C++ int minLength(const char *s); Java: public class Main { public static int minLength(String s); }
這道題目難度有三顆星吧,我的程序雖然通過了,但是我也不知道為什么要這么寫,只能說是直覺。。。
解題方法:
1、統計三個字母a,b,c的個數,分別為Acount, Bcount , Ccount;統計字符串的長度strlen;
2、通過一系列的數學證明,可知輸出結果僅為三種,即1、2或strlen:
若字符串中的字符均為a或b或c,那么輸出strlen;
若Acount, Bcount , Ccount均為奇數,那么輸出結果result = 2;
若Acount, Bcount , Ccount均為偶數,那么輸出結果result = 2;
若Acount, Bcount , Ccount有且僅有一個為偶數,那么輸出結果result = 1;
若Acount, Bcount , Ccount有且僅有一個為奇數,那么輸出結果result = 1;
#include <stdio.h> #include <stdlib.h> int ISeven(int n) { if(n % 2 == 0) return 1; else return 0; } int minLength(const char *s) { int Acount = 0, Bcount = 0, Ccount = 0, iterCount = 0 , Strlen = 0; for(iterCount = 0; s[iterCount] != '\000'; iterCount++) { switch(s[iterCount]) { case 'a': Acount++; break; case 'b': Bcount++; break; case 'c': Ccount++; break; } Strlen++; } if(Acount == Strlen || Bcount == Strlen || Ccount == Strlen ) { return Strlen; } printf("a:%d b:%d c:%d len = %d\n",Acount,Bcount,Ccount,Strlen); switch(ISeven(Acount) + ISeven(Bcount) +ISeven(Ccount)) { case 0: return 2; case 1: return 1; case 2: return 1; case 3: return 2; default: return 0; } } int main(void) { int result = 0; result = minLength("cccabcc"); printf("the minlen is %d\n",result); return 0; }