字符串消除
依旧是庞果网上的一道题目,详情如下:
给定一个字符串,仅由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; }