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. html5+css3 手机屏幕的适配css

    *{ margin:0;padding:0;outline:0}a{ text-decoration:none}body,html{ font-size:20px;font-family:'Micro ...

  2. 学习 HMM

    简介 HMM 中的变量可以分为两组. 第一组是状态变量 \(\{y_i,y_2,\cdots, y_n\}\), 其中 \(y_i \in \mathcal{Y}\) 表示第 \(i\) 时刻的系统状 ...

  3. mysql store procedure 存储过程

    参考资料: 1.http://blog.sina.com.cn/s/blog_52d20fbf0100ofd5.html 2.https://dev.mysql.com/doc/refman/5.7/ ...

  4. LOJ P3952 时间复杂度 noip 暴力 模拟

    https://www.luogu.org/problemnew/show/P3952 模拟,日常认识到自己zz. #include<iostream> #include<cstdi ...

  5. BZOJ.2125.最短路(仙人掌 圆方树)

    题目链接 圆方树.做题思路不写了.. 就是当LCA是方点时跳进那个环可以分类讨论一下用树剖而不必须用倍增: 如果v是u的(唯一的那个)重儿子,那么u的DFS序上+1的点即是要找的:否则v会引出一条新的 ...

  6. java知识点总结

    一.java 1.容器 1)List Java中ArrayList和LinkedList区别 2)Set 理解HashSet及使用 HashMap和HashSet的区别 3Map HashMap的容量 ...

  7. Python 学习笔记一

    前言 这篇博客是在学习某个网站时记录下来的,所以其纪录的顺序和那个网站里面一样,有些知识点已经大概了解了就不再赘述. 基础 字符串和编码 在计算机内存中,统一使用Unicode编码,当需要保存到硬盘或 ...

  8. Codeforces Round #288 (Div. 2) B. Anton and currency you all know 贪心

    B. Anton and currency you all know time limit per test 0.5 seconds memory limit per test 256 megabyt ...

  9. ASP.NET与MVC架构区别总结

    1)ASP.NET Webforms Behind Code利于快速开发,方便可视化操作. 2)ASP.NET 使用了“基于视图”的解决方案去应对“基于行为”的需求,它处理了客户端的请求,IIS将请求 ...

  10. js 闭包范式概述

    在前几篇文章中我介绍过js的闭包,这一篇主要简单的介绍一下js中闭包的范式. 那么何谓闭包的范式呢? 首先回想一下闭包的概念,闭包是外部函数与函数内部之间通信的桥梁,通过对函数的返回,使得外部的函数能 ...