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

v_JULY_v
博客专家认证
2013-12-31 11:10:34
加精
2014 新年将至,微软联合CSDN英雄会共同举办本次第三届在线编程大赛,题目详情如下:

有一个字符串"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取余数之后的结果。

咋?有思路了,立即参与挑战http://hero.csdn.net/Question/Details?ID=215&ExamID=210

参与挑战优秀的朋友,将有机会赢得微软提供的一二三等奖:
一等奖 1名 : 价值2199元的WindowsphoneNokiaLumia1020

二等奖 2名: 价值799元的微软无线蓝影键盘鼠标套装


三等奖 3名: 价值699元的微软Arc鼠标



奖品在那,去抢或有机会拿到,不抢,则失之交臂,伙伴们疯狂享受编程吧:http://hero.csdn.net/Question/Details?ID=215&ExamID=210,have fun!
...全文
4812 72 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
72 条回复
切换为时间正序
请发表友善的回复…
发表回复
computerhappy 2014-06-08
  • 打赏
  • 举报
回复
我是新手我不怕,呵呵
欢欢莓莓 2014-06-02
  • 打赏
  • 举报
回复
这是广告吗???
处处留心 2014-04-29
  • 打赏
  • 举报
回复
混个分的飘过
TheNewIpad 2014-04-29
  • 打赏
  • 举报
回复
搞不懂考什么呢。 还是我想的太简单了, 扫描一遍不就知道了么?
zcsking 2014-04-29
  • 打赏
  • 举报
回复
看到先想到三重循环 往下一拉都说超时。。
崦嵫 2014-03-29
  • 打赏
  • 举报
回复
比赛结果什么时候出来?
楊松坤 2014-02-19
  • 打赏
  • 举报
回复
QQ:125004485
dddjxyz 2014-01-26
  • 打赏
  • 举报
回复
int howmany (const char* s) { long long c_bing = 0ll,c_ing = 0ll, c_ng = 0ll, c_g = 0ll; int i = strlen(s)-1; for( ;i >=0 ;--i){ switch(s[i]){ case 'g': ++c_g; break; case 'n': c_ng += c_g; break; case 'i': c_ing += c_ng; break; case 'b': c_bing += c_ing; break; } } return c_bing%(1000000007); }
qc437700093 2014-01-24
  • 打赏
  • 举报
回复
class Test { public: static int howmany (string s) { unsigned long num_b=0,num_bi=0,num_bin=0,num_bing=0; for(int i=0;i<s.length();i++) { switch(s[i]) { case 'b': num_b=(num_b+1)%(1000000000+7); break; case 'i': num_bi=(num_bi+num_b)%(1000000000+7); break; case 'n': num_bin=(num_bin+num_bi)%(1000000000+7); break; case 'g': num_bing=(num_bing+num_bin)%(1000000000+7); break; } } return num_bing; } }; 这个代码,看看,大家认为咋样
lwouyang 2014-01-20
  • 打赏
  • 举报
回复
用aj表示字母a的第j次出现的位置(这里从0开始算)。 设 p("i", j) 为从字符串开始到 ij 的子字符串 substr(string, 0, ij) 中形成的"bi"的个数,规则与题目相同。 设 q("n", j, k) 为 nj 与nk 之间的字符 "n" 的前缀 "bi" 形成的次数。特别的,q("n", 0, j) 表示从字符串开始到 nj 之前的前缀 "bi" 形成的次数。 设 r("i", j) 为 ij 之前的字符 "b" 的个数,或者说在 ij 之前遇到的最后一个字符 "b" 是在 b_r("i", j) 位置,b_r("i", j) < ij。 例如,对于第 j 个字符 "b" 即 bj 而言,p("b", j) 表示从字符串开始到 bj 的子字符串 substr(string, 0, bj) 中字符 "b" 的个数,p("b", j) = j 或者说 p("b", j) = p("b", j-1) + 1, 如果 ik = bj + 1,即第 k 个字符 "i" 紧接在第 j 个字符 "b" 之后,有 r("i", k) = j = p("b", j)。 对于第 j 个字符 "i" 即 ij 而言,p("i", j) 不止包括 p("i", j-1),还因为这个 "i" 的出现而新增了 q("i", 0, j-1) 以及 i_j-1 与 ij 之间可能新出现的 "b" 而带来的 q("i", j-1, j),有 p("i", j) = p("i", j-1) + q("i", 0, j) + q("i", j-1, j)。 其中 q("i", 0, j-1) + q("i", j-1, j) = q("i", 0, j),因此 p("i", j) = p("i", j-1) + q("i", 0, j)。 另有 q("i", 0, j) = p["b", r("i", j)],因此 p("i", j) = p("i", j-1) + p["b", r("i", j)]。 同理, p("n", j) = p("n", j-1) + p["i", r("n", j)], p("g", j) = p("g", j-1) + p["g", r("g", j)]。 设字符串中字符 "g" 的个数为 m,则 p("g", m) 为所求。 只需从左至右扫描一次字符串,依次计算遇到的每个字符 a 的 p(a, j),复杂度为 O(n).
hui211314ddhui 2014-01-15
  • 打赏
  • 举报
回复
引用 61 楼 lxb365 的回复:
#include<stdio.h>
#include<string.h>
int howmany (char* s)
{
long long b = 0,bi = 0,bin = 0, bing = 0;
unsigned int i=0
for (; i < strlen(s); i++)
{
switch (*(s+i))
{
case 'b':
b++;
break;
case 'i':
bi+= b;
break;
case 'n':
bin+= bi;
break;
case 'g':
bing+= bin;
break;
}
}

return (int)(bing%1000000007);
}


使用逆推的思想,在遍历过程中,当出现'g'的时候,当前已经出现的"bin"和这个'g'都可以组成"bing",那么"bing"的个数也就增加"bin"的个数;同理“bin”和“bi”的个数也这么算,O(n)算出结果。

跟我的思路一样。
lxb365 2014-01-10
  • 打赏
  • 举报
回复
#include<stdio.h>
#include<string.h>
int howmany (char* s)
{
	long long b = 0,bi = 0,bin = 0, bing = 0;
	unsigned int i=0
    for (; i < strlen(s); i++)
    {
        switch (*(s+i))
        {
		case 'b':
				b++;
                break;
		case 'i':                                  
                bi+= b;
                break;
		case 'n':                 
                bin+= bi;
                break;
		case 'g':                
                bing+= bin;
                break;          
        }
    }
    
    return (int)(bing%1000000007);
}
使用逆推的思想,在遍历过程中,当出现'g'的时候,当前已经出现的"bin"和这个'g'都可以组成"bing",那么"bing"的个数也就增加"bin"的个数;同理“bin”和“bi”的个数也这么算,O(n)算出结果。
SKATE11 2014-01-07
  • 打赏
  • 举报
回复
楼主的《编程艺术》很不错
StuClass 2014-01-07
  • 打赏
  • 举报
回复
引用 25 楼 huang369509940 的回复:
引用 22 楼 StuClass 的回复:
[quote=引用 4 楼 huang369509940 的回复:] 广告嘛、、、那来混个分好了、、、
我擦,黄大仙!你知道CDUT吗?
成都理工大学??刚百度的 = =[/quote]看来你不是我认识的黄大仙
icesnack 2014-01-07
  • 打赏
  • 举报
回复
引用 39 楼 longteng1116 的回复:
[quote=引用 38 楼 q745401990 的回复:] [quote=引用 36 楼 longteng1116 的回复:] 通过了,可惜第一次挑战失败了,用了一个马甲提交挑战成功。最后怎么评奖呢?
求如何切?[/quote] 第一个版本: 定义b[],i[],j[],g[]数组,分别记录b,i,n,g的位置,然后开始计算,主要是进行嵌套比较,复杂度O(n^4). 必然超时; 第二个版本: 增加r_b[],r_i[],r_j[],r_g[]数组,分别记录对应b[],i[],j[],g[]可满足结果,从r_g[]开始,初始全1;然后计算r_j[],再计算r_i[],再计算r_b[],复杂度O(n^2),测试了一下连续2500个b....i....n....g...的组合,时间大概10秒左右,还是超时; 第三个版本: 在计算r_b[],r_i[],r_j[],r_g[]时进行控制,复杂度可缩小为O(n),通过。 比如:iinbinbing b[]:3,6 i[]: 0,1,4,7 n[]:2,5,8 g[]:9 得到: r_g[]: 1 r_n[]: 1,1,1 r_i[]: 3,3,2,1 r_b[]:3,1 最后的结果就是sum(r_b[]) = 3 + 1 = 4 不知道有没有分析清楚,具体的解释后续放博客里。 [/quote]我一开始的思路就是这个啊,可惜没处理空字符串,抛异常了,郁闷啊。。。
xusir98 2014-01-07
  • 打赏
  • 举报
回复
Hope_f 2014-01-06
  • 打赏
  • 举报
回复
引用 55 楼 u013288655 的回复:
[quote=引用 54 楼 aa512690069 的回复:] 这个是我提交的。
贴代码之前,别忘了先说下自己的思路哦,方便他人理解。[/quote] http://blog.csdn.net/aa512690069/article/details/17918799,这个是我整理的思路。谢谢.欢迎交流.
u013288655 2014-01-06
  • 打赏
  • 举报
回复
引用 54 楼 aa512690069 的回复:
这个是我提交的。
int howmany (const char* s)
{    
    unsigned int len = 0;
    const char* e = s;
    const char* key = "bing";
    const char* ke = key;
    unsigned int keyLen = 0;
    long long num = 0;
    long long* bing = 0;
    int idx[256] = {0};
    unsigned int i = 0;

    if(s == 0 || *s == 0) return 0;
    
    while(*ke++ != 0);
    while(*++e != 0);
    keyLen = ke - key - 1;

    bing = (long long*)malloc(sizeof(long long) * keyLen);
    for(i = 0; i < keyLen; ++i)
    {
        idx[key[i]] = i + 1;
        bing[i] = 0;
    }

    for (--e; e >= s; --e)
    {
        int n = idx[*(unsigned char*)e];

        if(!n)
            continue;
        
        if(n == keyLen)
        {
            bing[n - 1]++;
        }
        else
        {
            if(bing[n] > 0)
                bing[n - 1] += bing[n];
        }
    }

    num = bing[0];
    free(bing);
    return num % 1000000007;
}
贴代码之前,别忘了先说下自己的思路哦,方便他人理解。
Hope_f 2014-01-05
  • 打赏
  • 举报
回复
这个是我提交的。
int howmany (const char* s)
{    
    unsigned int len = 0;
    const char* e = s;
    const char* key = "bing";
    const char* ke = key;
    unsigned int keyLen = 0;
    long long num = 0;
    long long* bing = 0;
    int idx[256] = {0};
    unsigned int i = 0;

    if(s == 0 || *s == 0) return 0;
    
    while(*ke++ != 0);
    while(*++e != 0);
    keyLen = ke - key - 1;

    bing = (long long*)malloc(sizeof(long long) * keyLen);
    for(i = 0; i < keyLen; ++i)
    {
        idx[key[i]] = i + 1;
        bing[i] = 0;
    }

    for (--e; e >= s; --e)
    {
        int n = idx[*(unsigned char*)e];

        if(!n)
            continue;
        
        if(n == keyLen)
        {
            bing[n - 1]++;
        }
        else
        {
            if(bing[n] > 0)
                bing[n - 1] += bing[n];
        }
    }

    num = bing[0];
    free(bing);
    return num % 1000000007;
}
afrazhu 2014-01-04
  • 打赏
  • 举报
回复
next
加载更多回复(50)

65,189

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧