幾個bing的c#求解--微軟必應·英雄會第三屆在線編程大賽

      這幾天閒來無事,看到這個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;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章