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取余数之后的结果。

这个问题写个四重循环就可以.只是效率方面还有待优化.

第一版代码:

 #include <stdio.h>
#include <iostream>
#include <string> #include <cstring>
#include <cstdio> #define BING_MAX 1000000007 int Bing(const char* szBing)
{
if (!szBing || !szBing[])
{
return ;
} int len = (int)strlen(szBing);
int* listPosB = (int*)malloc(len*sizeof(int));
int* listPosI = (int*)malloc(len*sizeof(int));
int* listPosN = (int*)malloc(len*sizeof(int));
int* listPosG = (int*)malloc(len*sizeof(int));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
switch (szBing[i])
{
case 'B':
case 'b':
listPosB[numB] = i;
numB++;
break;
case 'I':
case 'i':
listPosI[numI] = i;
numI++;
break;
case 'N':
case 'n':
listPosN[numN] = i;
numN++;
break;
case 'G':
case 'g':
listPosG[numG] = i;
numG++;
break;
}
} int count = ; int startB;
int startI;
int startN;
int startG;
for (int b = ; b < numB; b++)
{
startB = listPosB[b]; for (int i = ; i < numI; i++)
{
startI = listPosI[i];
if (startI < startB)
{
continue;
} for (int n = ; n < numN; n++)
{
startN = listPosN[n];
if (startN < startI)
{
continue;
} for (int g = ; g < numG; g++)
{
startG = listPosG[g];
if (startG < startN)
{
continue;
} count++;
if (count > BING_MAX)
{
count -= BING_MAX;
}
}
}
}
} free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}

优化后的代码:

 #include <cstring>
#include <cstdio> #define BING_MAX 1000000007 struct U2
{
short pos;
short next;
}; int Bing(const char* szBing)
{
if (!szBing || !szBing[])
{
return ;
} int len = (int)strlen(szBing);
U2* listPosB = (U2*)malloc(len*sizeof(U2));
U2* listPosI = (U2*)malloc(len*sizeof(U2));
U2* listPosN = (U2*)malloc(len*sizeof(U2));
U2* listPosG = (U2*)malloc(len*sizeof(U2));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
switch (szBing[i])
{
case 'B':
case 'b':
listPosB[numB].pos = (short)i;
numB++;
break;
case 'I':
case 'i':
listPosI[numI].pos = (short)i;
numI++;
break;
case 'N':
case 'n':
listPosN[numN].pos = (short)i;
numN++;
break;
case 'G':
case 'g':
listPosG[numG].pos = (short)i;
numG++;
break;
}
} for (int i = ; i < numB; i++)
{
for (int j = ; j < numI; j++)
{
if (listPosB[i].pos < listPosI[j].pos)
{
listPosB[i].next = j;
break;
}
}
} for (int i = ; i < numI; i++)
{
for (int j = ; j < numN; j++)
{
if (listPosI[i].pos < listPosN[j].pos)
{
listPosI[i].next = j;
break;
}
}
} for (int i = ; i < numN; i++)
{
for (int j = ; j < numG; j++)
{
if (listPosN[i].pos < listPosG[j].pos)
{
listPosN[i].next = j;
break;
}
}
} int count = ;
for (int b = ; b < numB; b++)
{
for (int i = listPosB[b].next; i < numI; i++)
{
for (int n = listPosI[i].next; n < numN; n++)
{
for (int g = listPosN[n].next; g < numG; g++)
{
count++;
if (count > BING_MAX)
{
count -= BING_MAX;
}
}
}
}
} /*
short startB;
short startI;
short startN;
short startG;
for (int b = 0; b < numB; b++)
{
startB = listPosB[b].pos; for (int i = 0; i < numI; i++)
{
startI = listPosI[i].pos;
if (startI < startB)
{
continue;
} for (int n = 0; n < numN; n++)
{
startN = listPosN[n].pos;
if (startN < startI)
{
continue;
} for (int g = 0; g < numG; g++)
{
startG = listPosG[g].pos;
if (startG < startN)
{
continue;
} count++;
if (count > BING_MAX)
{
count -= BING_MAX;
}
}
}
}
}
*/ free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}

第三版优化,还是运行时间超过3s,我是真没辙了.

 #include <cstring>
#include <cstdio>
#include <assert.h> #define BING_MAX 1000000007 struct U2
{
short pos;
short next;
}; int Bing(const char* szBing, int len)
{
if (!szBing || !szBing[])
{
return ;
} U2* listPosB = (U2*)malloc(len*sizeof(U2));
U2* listPosI = (U2*)malloc(len*sizeof(U2));
U2* listPosN = (U2*)malloc(len*sizeof(U2));
U2* listPosG = (U2*)malloc(len*sizeof(U2));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
if (szBing[i] == 'b')
{
listPosB[numB].pos = (short)i;
numB++;
}
else if (szBing[i] == 'i')
{
listPosI[numI].pos = (short)i;
numI++;
}
else if (szBing[i] == 'n')
{
listPosN[numN].pos = (short)i;
numN++;
}
else
{
listPosG[numG].pos = (short)i;
numG++;
}
} int t = ;
for (int i = ; i < numB; i++)
{
for (int j = t; j < numI; j++)
{
if (listPosB[i].pos < listPosI[j].pos)
{
listPosB[i].next = t = j;
break;
}
}
} t = ;
for (int i = ; i < numI; i++)
{
for (int j = t; j < numN; j++)
{
if (listPosI[i].pos < listPosN[j].pos)
{
listPosI[i].next = t = j;
break;
}
}
} t = ;
for (int i = ; i < numN; i++)
{
for (int j = t; j < numG; j++)
{
if (listPosN[i].pos < listPosG[j].pos)
{
listPosN[i].next = t = j;
break;
}
}
} int count = ;
for (int b = ; b < numB; b++)
{
for (int i = listPosB[b].next; i < numI; i++)
{
for (int n = listPosI[i].next; n < numN; n++)
{
count += numG - listPosN[n].next;
}
} if (count > BING_MAX)
{
count -= BING_MAX;
}
} free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}

第四版代码:

 #include <cstring>
#include <cstdio> #define BING_MAX 1000000007 struct U2
{
int pos;
int count;
}; int Bing(const char* szBing, int len)
{
if (!szBing || !szBing[])
{
return ;
} U2* listPosB = (U2*)malloc(len*sizeof(U2));
U2* listPosI = (U2*)malloc(len*sizeof(U2));
U2* listPosN = (U2*)malloc(len*sizeof(U2));
U2* listPosG = (U2*)malloc(len*sizeof(U2));
memset(listPosB, , len*sizeof(int));
memset(listPosI, , len*sizeof(int));
memset(listPosN, , len*sizeof(int));
memset(listPosG, , len*sizeof(int));
int numB = ;
int numI = ;
int numN = ;
int numG = ; for (int i = ; i < len; i++)
{
if (szBing[i] == 'b')
{
listPosB[numB].pos = i;
numB++;
}
else if (szBing[i] == 'i')
{
listPosI[numI].pos = i;
numI++;
}
else if (szBing[i] == 'n')
{
listPosN[numN].pos = i;
numN++;
}
else if (szBing[i] == 'g')
{
listPosG[numG].pos = i;
numG++;
}
} int b = ;
int i = ;
int n = ;
int g = ;
int t; // 每个N之后有多少个G的选择
for (n = ; n < numN; n++)
{
while (listPosG[g].pos < listPosN[n].pos && g < numG)
{
g++;
}
listPosN[n].count = numG - g;
} // 每个I之后有多少个NG的选择
n = ;
for (i = ; i < numI; i++)
{
while (listPosN[n].pos < listPosI[i].pos && n < numN)
{
n++;
}
listPosI[i].count = ;
for (t = n; t < numN; t++)
{
listPosI[i].count += listPosN[t].count;
}
} // 每个B之后有多少个ING的选择
i = ;
int count = ;
for (int b = ; b < numB; b++)
{
while (listPosI[i].pos < listPosB[b].pos && i < numI)
{
i++;
}
listPosB[b].count = ;
for (t = i; t < numI; t++)
{
listPosB[b].count += listPosI[t].count;
} count += listPosB[b].count;
if (count > BING_MAX)
{
count -= BING_MAX;
}
} free(listPosB);
free(listPosI);
free(listPosN);
free(listPosG); return count;
}

终于想到正确答案了,原来我一开始就误入歧途了,最早的代码算法复杂度是O(n^4),我将其优化到O(n^2),然后又优化到O(n*log(n)),而最终代码的复杂度是O(n).

 #define BING_MAX 1000000007

 int Bing(const char* szBing)
{
int numB = ;
int numI = ;
int numN = ;
int numG = ;
int pos = ;
while (szBing[pos])
{
if (szBing[pos] == 'b')
{
numB++;
}
else if (szBing[pos] == 'i')
{
numI += numB;
}
else if (szBing[pos] == 'n')
{
numN += numI;
}
else if (szBing[pos] == 'g')
{
numG += numN;
if (numG > BING_MAX)
{
numG -= BING_MAX;
}
}
pos++;
} return numG;
}

给定任意字符串,计算一共能组合成多少个单词bing的更多相关文章

  1. 给定任意一个字符串,使用 for in 语句来统计字符出现的个数

    //找出字符串中的数字 var str = 'haj123sdk54hask33dkhalsd879'; /*function findNum(str){ var arr = []; var tmp ...

  2. 在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作。一次移动操作指用一个"LX"替换一个"XL",或者用一个"XR"替换一个"RX"。现给定起始字符串start和结束字符串end,请编写代码,当且仅当存在一系列移动操作使得start可以转换成end时, 返回True。

    在一个由 'L' , 'R' 和 'X' 三个字符组成的字符串(例如"RXXLRXRXL")中进行移动操作.一次移动操作指用一个"LX"替换一个"XL ...

  3. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字符不改变,给定函数,编写函数 void Stringchang(const char*input,char*output)其中input是输入字符串,output是输出字符串

    import java.util.Scanner; /*** * 1. 给定一个字符串,把字符串内的字母转换成该字母的下一个字母,a换成b,z换成a,Z换成A,如aBf转换成bCg, 字符串内的其他字 ...

  4. 编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成

    编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成.“组合 ”的规则如下: 1). str中的每个字母要么来自于part1,要么来自于part2 ...

  5. 给定一个字符串,仅由a,b,c 3种小写字母组成。

    package com.boco.study; /** * 题目详情 给定一个字符串,仅由a,b,c 3种小写字母组成. 当出现连续两个不同的字母时,你可以用另外一个字母替换它,如 有ab或ba连续出 ...

  6. Oracle中如何判断字符串是否全为数字,以及从任意字符串中提取数字

    本文介绍了判断字符串是否全为数字的4种办法,另外还介绍了一个translate函数的小技巧,从任意字符串中提取数字(调用2次translate函数).这个办法是一个公司同事发现的,用起来很方便,但理解 ...

  7. JS求任意字符串中出现最多的字符以及出现的次数

    我爱撸码,撸码使我感到快乐!大家好,我是Counter本节讲讲如何利用JS来查找任意给定的字符串,求字符串中出现次数最多的字符,出现的次数.直接上代码了,该注释的都注释啦.非常轻松加愉快.效果如下: ...

  8. 将一个字符串中的空格替换成“%20”(C、Python)

    将一个字符串中的空格替换成“%20” C语言: /* ----------------------------------- 通过函数调用,传地址来操作字符串 1.先计算出替换后的字符串的长度 2.从 ...

  9. delphi string.split 按照任意字符串分割语句

    delphi string.split 按照任意字符串分割语句 1.就是把一个指定的字符串用指定的分割符号分割成多个子串,放入一个 TStringList 中 function ExtractStri ...

随机推荐

  1. Ionic入门四:卡片

    近年来卡片(card)的应用越来越流行,卡片提供了一个更好组织信息展示的工具. 针对移动端的应用,卡片会根据屏幕大小自适应大小. 我们可以很灵活的控制卡片的显示效果,甚至实现动画效果. 卡片一般放在页 ...

  2. 洛谷 P3071 [USACO13JAN]座位Seating-线段树区间合并(判断找,只需要最大前缀和最大后缀)+分治+贪心

    P3071 [USACO13JAN]座位Seating 题目描述 To earn some extra money, the cows have opened a restaurant in thei ...

  3. linux 杂类

    1.linux 下替换windows换行符命令   set ff=unix(命令行)

  4. JDK源码分析(二)——LinkedList

    目录 LinkedList LinkedList继承结构 LinkedList内部类Node LinkedList成员属性 LinkedList构造方法 重要方法 Deque方法的实现 遍历 总结 L ...

  5. NetCore+Dapper WebApi架构搭建(一):基本框架

    初衷是想用dapper搭建一个高性能的架构,因为dapper操作数据库的效率很高 1.VS创建一个NetCore WebApi的框架,然后解决方案添加一个NetStandard的类库 整个解决方案如图 ...

  6. 配置k8s dns

    DNS (domain name system),提供域名解析服务,解决了难于记忆的IP地址问题,以更人性可读可记忆可标识的方式映射对应IP地址. Cluster DNS扩展插件用于支持k8s集群系统 ...

  7. Codeforces 1090J $kmp+hash+$二分

    题意 给出两个字符串\(s\)和\(t\),设\(S\)为\(s\)的任意一个非空前缀,\(T\)为\(t\)的任意一个非空前缀,问\(S+T\)有多少种不同的可能. Solution 看了一圈,感觉 ...

  8. 【平面图最小割】BZOJ1001- [BeiJing2006]狼抓兔子

    [题目大意]左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下三种类型的道路 1:(x,y)<==>(x+1,y) 2:(x,y)<==>(x,y+1) ...

  9. Beego 和 Bee 的开发实例

    Beego不是一般的web开发包.它构建在大量已存在的Go之上,提供了许多的功能,以下是提供的功能: 一个完整的ORM 缓存 支持session 国际化(i18n) 实时监测和重载 发布支持 ==== ...

  10. tyvj:1520 树的直径 spfa/树的直径

    tyvj:1520 树的直径 Time Limit: 1 Sec  Memory Limit: 131072KiBSubmit: 9619  Solved: 3287 题目连接 http://www. ...