字符串消除

依旧是庞果网上的一道题目,详情如下:

给定一个字符串,仅由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;
}

 

posted on 2013-08-27 13:24  大卫david  阅读(1364)  评论(20编辑  收藏  举报

导航