几个bing的c#求解--微软必应·英雄会第三届在线编程大赛

来源:互联网 发布:淘宝搜索量排名 编辑:程序博客网 时间:2024/04/29 06:21

      这几天闲来无事,看到这个bing的题,感觉并不是很难,于是就把它写下来。

先看题目:

本届大赛由微软必应词典冠名,必应词典(Bing Dictionary)是微软推出的新一代英语学习引擎,里面收录了很多我们常见的单词,详情请见:http://cn.bing.com/dict/?form=BDVSP4&mkt=zh-CN&setlang=ZH。但现实生活中,我们也经常能看到一些毫无规则的字符串,导致词典无法正常收录,不过,我们是否可以从无规则的字符串中提取出正规的单词呢?

   例如有一个字符串"iinbinbing",截取不同位置的字符‘b’、‘i’、‘n’、‘g’组合成单词"bing"。若从1开始计数的话,则‘b’ ‘i’ ‘n’ ‘g’这4个字母出现的位置分别为(4,5,6,10) (4,5,9,10),(4,8,9,10)和(7,8,9,10),故总共可以组合成4个单词”bing“。

  咱们的问题是:现给定任意字符串,只包含小写‘b’ ‘i’ ‘n’ ‘g’这4种字母,请问一共能组合成多少个单词bing?

  字符串长度不超过10000,由于结果可能比较大,请输出对10^9 + 7取余数之后的结果。

解题思路:

统计一下每一个b后面出现了多少个i,每个i后面出现了多少个n,每个n后面出现了多少个g

然后用递归调用,从b的集合开始循环,统计每个b后面有多少个,依次递归调用,调用i集合,调用n集合,因为g是最后一个,所以就不用调用了

 

先看第一步,统计

int bindex = -1;
            int iindex = -1;
            int nindex = -1;
            int gindex = -1;
            int count = 0;
            string t="";
            for (int i = 0; i < s.Length; i++)
            {
                t = s.Substring(i, 1);
                if (t == "b")
                {
                    BList.Add(0);
                    bindex = BList.Count - 1;
                }
                if (t == "i")
                {
                    IList.Add(0);
                    iindex = IList.Count - 1;
                    if (bindex != -1)
                    {
                        BList[bindex]++;
                    }
                }
                if (t == "n")
                {
                    NList.Add(0);
                    nindex = NList.Count - 1;
                    if (iindex != -1)
                    {
                        IList[iindex]++;
                    }
                }
                if (t == "g")
                {
                    GList.Add(0);
                    gindex = GList.Count - 1;
                    if (nindex != -1)
                    {
                        NList[nindex]++;
                    }
                }
            }

这个统计,并不是累计统计,所以需要一次累计统计:

for(int i = BList.Count - 2; i >= 0; i--)

    Blist[i]+=BList[i-1];

分别累计统计后,然后开始递归调用

递归函数如下:

public static int CalCount(List<int> list,int start, int step)
        {
            long count = 0;
            List<int> nextlist=null;
            if(step==1)
            {
                nextlist=IList;
            }
            if(step==2)
            {
                nextlist =NList;
            }
           
            for (int i = start; i < list.Count; i++)
            {
                if (step == 3)
                {
                    count += list[i];
                    count = count % 1000000007;
                }
                else
                {
                    if (step == 2)
                    {
                        if (ICacheList.ContainsKey(i))
                        {
                            count += ICacheList[i];
                            count = count % 1000000007;
                        }
                        else
                        {
                            if (list[i] > 0)
                            {

                                ICacheList.Add(i, CalCount(nextlist, nextlist.Count - list[i], step + 1));
                                count += ICacheList[i];
                                count = count % 1000000007;
                            }
                            else
                            {
                                ICacheList.Add(i, 0);
                            }
                        }
                    }
                    else
                    {
                        count += CalCount(nextlist, nextlist.Count - list[i], step + 1);
                        count = count % 1000000007;
                    }
                }
            }
            return (int)(count%1000000007);
        }

其中对i集合计算的时候,会重复做无用功,所以,用个缓存集合缓存一下数据

调用就是

表示从b集合开始循环调用,从索引为0的开始统计,表示bing的第一个字符

count = CalCount(BList, 0, 1);

结果还行,10000的长度字符串,本机运行没超过1秒,提交上去后,悲剧了,提示超过3s,吧10000放大到100000,时间好长,看来这种递归方式还是存在问题的。

不过这道题感觉不需要这么多的递归调用啊

再次分析:根据题目,从i分析的时候,可以看出,递归是不需要那么多的,反过来推断,b,n集合也是。

因此改造下对几个集合的统计,那么就不需要递归调用了,统计结果

for (int i = NList.Count - 1; i >= 0; i--)
            {
                if (i == NList.Count - 1)
                {
                    count = NList[i];
                }
                else
                {
                    count += NList[i];
                    NList[i] = NList[i + 1]+count;
                    count = count % 1000000007;
                    NList[i] = NList[i] % 1000000007;
                }
            }
            count = 0;
            for (int i = IList.Count - 1; i >= 0; i--)
            {
                if (i == IList.Count - 1)
                {
                    count = IList[i];
                    if (count != 0)
                    {
                        IList[i] = NList[NList.Count - count];
                    }
                    else
                    {
                        IList[i] = 0;
                    }
                }
                else
                {
                    count += IList[i];
                    if (count != 0)
                    {
                        IList[i] = IList[i + 1] + NList[NList.Count - count];
                    }
                    else
                    {
                        IList[i] = IList[i + 1];
                    }
                    count = count % 1000000007;
                    IList[i] = IList[i] % 1000000007;
                }
               
            }
            count = 0;
            for (int i = BList.Count - 1; i >= 0; i--)
            {
                if (i == BList.Count - 1)
                {
                    count = BList[i];
                    if (count != 0)
                    {
                        BList[i] = IList[IList.Count - count];
                    }
                    else
                    {
                        BList[i] = 0;
                    }
                }
                else
                {
                    count += BList[i];
                    if (count != 0)
                    {
                        BList[i] = BList[i + 1] + IList[IList.Count - count];
                    }
                    else
                    {
                        BList[i] = BList[i + 1];
                    }
                    count = count % 1000000007;
                    BList[i] = BList[i] % 1000000007;
                }
            }
           
           
            //count = CalCount(BList, 0, 1);
            //int result=(int)(count % 1000000007);
            int result = 0;
            if (BList.Count > 0)
                result = BList[0];
            return result;

0 0
原创粉丝点击