微软必应·英雄会第三届在线编程大赛:几个bing?

来源:互联网 发布:linux 怎么解压rar 编辑:程序博客网 时间:2024/04/29 15:08
题目详情

    本届大赛由微软必应词典冠名,必应词典(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取余数之后的结果。

选择方法二,结果失败了!
方法一:递归过多堆栈溢出(字符串长度不能超过几百)
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Bing个数{    /// <summary>    /// 一、首先去掉字符串首尾的无关字符,使其成为如下格式:b......g    /// 二、确定"b"后第一个"i"后"n"的个数计数;再找第二个"i"后"n"的个数计数...直到所有的"i"后"n"都被找完。    /// 三、确定倒数第二个"g"字符(去掉字符串右端的无关字符),递归步骤二...直到第一个有用的"g"被找完    /// 四、确定第二个"b"(去掉字符串左端的无关字符),重复步骤二、三...直到最后一个有用的"b"被找完    /// </summary>    class Program    {        /// <summary>        /// b......g间所能组成bing所有方案个数        /// </summary>        /// <param name="oldstr"> 原先字符串 </param>        /// <param name="newstr"> 操作字符串,通过"i"找到后面"n"的个数 </param>        /// <param name="count"> 个数</param>        /// <returns></returns>        public static void getCount( string oldstr, string newstr, ref int count)        {            //newstr = "hjsdhifdnnsi";            int indexI = newstr.IndexOf('i' );            if (indexI > 0)            {                StringBuilder m = new StringBuilder();                StringBuilder n = new StringBuilder();                //m = new StringBuilder(newstr.Substring(indexI));                m = new StringBuilder (newstr).Remove(0, indexI);                //此"i"位置后所有"n"的个数                count += ( from c in m.ToString() where c == 'n' select c).Count();                //去掉当前"i"                //newstr = newstr.Remove(indexI, 1);                n = new StringBuilder (newstr).Remove(indexI, 1);                newstr = n.ToString();                m.Clear();                n.Clear();                //递归                getCount(oldstr, newstr, ref count);            }            else            {                if (oldstr.IndexOf('i' ) > 0 && oldstr.Length >= 4)                {                    //b...g,找到字符串末端第2个"g"字符递归                    oldstr = oldstr.Remove(oldstr.Length - 1, 1).TrimEnd( new char [] { 'i', 'n', 'b' });                    newstr = oldstr;                    getCount(oldstr, newstr, ref count);                }            }        }        static void Main(string[] args)        {            int n = 0, count = 0, totalCount = 0;            string[] bing = new [] { "b", "i", "n" , "g" };            StringBuilder bingStringBuilder = new StringBuilder();            Random r = new Random();            for (int i = 0; i < 10000; i++)            {                n = r.Next(0, 4);                bingStringBuilder = bingStringBuilder.Append(bing[n]);            }            //创建只包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串            string bingStr = bingStringBuilder.ToString();            //去掉首尾不能组合成bing的字符即b......g            bingStr = bingStr.TrimStart( new char [] { 'i', 'n', 'g' }).TrimEnd( new char [] { 'i', 'n', 'b' });            while ((from c in bingStr where c == 'b' select c).Count() != 0)            {                //b......g格式下bing个数                getCount(bingStr, bingStr, ref count);                totalCount += count;                //去掉字符"b"                bingStr = bingStr.Remove(0, 1);                //b......g,确定下一个"b"字符                bingStr = bingStr.TrimStart( new char [] { 'i', 'n', 'g' });                count = 0;            }            Console.WriteLine("包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串为:" + bingStringBuilder);            Console.WriteLine();            Console.WriteLine("组合成单词\"bing\"的个数:" + totalCount);            Console.WriteLine();            Console.WriteLine("输出对10^9 + 7取余数之后的结果:" + totalCount % 1000000007 );            Console.ReadLine();        }    }}
方法二:当字符串长度为10000时运行超时(整个下来会非常耗时,用Stopwatch测了下差不多要8分钟)改为1000了,对10^9 + 7取余数之后的结果(悲催的写成1000000007 % totalCount了)挑战失败!
using System;using System.Collections;using System.Collections.Generic;//using System.Linq;using System.Text;/// <summary>/// 解题思路:/// 一、创建只包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串bingStr,用两个数据集合iList与gList记录下字符"i","g"的所在位置/// 二、遍历iList集合,记录字符"i"前字符"b"的个数;在遍历中嵌套循环gList集合,记录字符"i"与字符"g"间字符"n"的个数。两者相乘累加即为所求/// </summary>public class Test {   public static  int howmany(string s)    {        return 0;    }    //start 提示:自动阅卷起始唯一标识,请勿删除或增加。     public static void Main()    {        int n = 0;        long totalCount = 0;        string[] bing = new[] { "b", "i", "n", "g" };        StringBuilder bingStringBuilder = new StringBuilder();        List<int> iList = new List<int>();        List<int> gList = new List<int>();        Random r = new Random();        for (int i = 0; i < 1000; i++)        {            n = r.Next(0, 4);            bingStringBuilder = bingStringBuilder.Append(bing[n]);            if (bing[n] == "i")            {                iList.Add(i);            }            if (bing[n] == "g")            {                gList.Add(i);            }        }        //创建只包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000的字符串        string bingStr = bingStringBuilder.ToString();        foreach (int i in iList)        {            //当前字符"i"前的字符串子串            string bingStrLeft = bingStr.Substring(0, i);            //当前字符"i"前字符"b"的个数            //int bCount = (from c in bingStrLeft where c == 'b' select c).Count();            int bCount = bingStrLeft.Replace("i", "").Replace("n", "").Replace("g", "").Length;            if (bCount > 0)            {                foreach (int g in gList)                {                    //字符"i"在字符"g"前                    if (g > i)                    {                        //当前字符"i"后字符"g"前(不包含字符"g")的字符串子串                        string subBingStr = bingStr.Substring(i, g - i);                        //此字符串间字符"n"的个数                        //int nCount = (from c in subBingStr where c == 'n' select c).Count();                        int nCount = subBingStr.Replace("b", "").Replace("i", "").Replace("g", "").Length;                        //字符"i"字符"g"固定时所能组成"bing"的总个数                        totalCount += bCount * nCount;                    }                }            }        }        Console.WriteLine("包含字符‘b’、‘i’、‘n’、‘g’且长度不超过10000(实际长度为1000)的字符串为:" + bingStr);        Console.WriteLine();        Console.WriteLine("组合成单词\"bing\"的个数:" + totalCount);        Console.WriteLine();        Console.WriteLine("输出对10^9 + 7取余数之后的结果:" + (totalCount == 0 ? 0 : (totalCount % 1000000007)));    }    //end //提示:自动阅卷结束唯一标识,请勿删除或增加。}




0 0