您的位置:首页 > 其它

美团点评2016研发工程师在线笔试题解一

2018-03-11 16:23 357 查看
总共六道编程题,先从第5题写吧,因为比较有成就感,原题是在牛客网做的,刚开始不会做,
不过看了讨论区的讨论,看不懂怎么做的,有用动态规划的,有用二进制的,各路大神都有,
虽然通过了牛客的测试,但是我试了几个例子,居然输出负数,无奈只好自己做了,花了一整天
按我自己的思路做了出来,自己还算比较才满意。
题目描述:求字典序在s1和s2之间的,长度在len1到len2的字符串的个数,结果mod1000007
输入描述:每组数据包含s1(长度小于100),s2(长度小于100),len1(小于100000),len2(大于len1,小于100000)
输出描述:输出答案
示例
输入: ab  ce  1  2
输出:56
示例分析:所求字符串str的字典序在ab和ce之间,长度在1到2之间,满足条件的有ac~az,ba~bz,b,c,ca~cd,共计24+26+2+4=56个(个人觉得题目没什么理解难度,不知道为什么很多人不理解题目)。
解析:我解答是首先是从一个测试样例开始的,因为我的代码第一个测试样例不过,str1=cpqejrrgp, str2=cpqejtrdg,len1=9,len2=9(输出应该为35064)。
第一步:首先找到两个字符串str1和str2相对位置第一个不相同的位置,若以示例中的例子为例ab和ce,第一个相对位置不相等的位置下标为0即a和c不相等,用k记录位置下标,若以我的第一个测试样例为例,str1=cpqejrrgp和str2=cpqejtrdg,第一个相对不相等的位置下标为5,即k=5时,str1[k]=r,str2[k]=t,二者第一次不相等。当找到第一个相对位置不相等的下标k;
第二步:先求在k位置处,所求字符串的str[k]>str1[k] && str[k]<str2[k]的情况有多少种,这个是最好算的,只要满足str[k]>str1[k]&&str[k]<str2[k],后面的位置可以在a~z之间随便取。例如str1=cpqejrrgp,str2=cpqejtrdg,str[5]>r && str[5]<t 即str[5]=s时,后面的三个位置str[6],str[7],str[8]随意取,共有pow(26,len1-1-k)种,若len2>len2,还需要写一个for循环,pow函数中的参数需要从len1-1-k到len2-1-k分别计算,最后累加,代表str的长度分别为len1,len1+1,.....,len2时各有多少种;
第三步:其次再求str[k]==str1[k]时str有多少种。此时,str1[k+1]需大于str1[k+1],str[k+2]、str[k+3]、...、str[len2-1]可以随意取;接着再求str[k]==str1[k] && str[k+1]==str1[k+1]时str有多少种,此时str[k+2]需大于str1[k+2],str[k+3].....str[len2-1]可以随便取,以此类推,直到str[k]==str1[k]&&str[k+1]&&..&&str[len2-2]==str1[len2-2]为止,将所有计算情况相加;
第四步:再次计算str[k]==str2[k]时str有多少种,此时,str[k+1]需小于str2[k+1],str[k+2]....str[len2-1]可以随意取值;再接着求str[k]==str2[k]&&str[k+1]==str2[k+1]时,str[k+2]...str[len2-1]位置可以随意取;以此类推,直到求出str[k]==str2[k] && str[k+1]==str2[k+1] && ...&& str[len2-2]==str2[len2-2]为止,所有情况数累加;
第五步:把第二步、第三步、第四步的所有情况累加取模,即可求出总数(注意求解过程中的边界问题一定要判断好,且无论如何,输出不可能为负数,测试样例1:abbv abba 4 4,应输出:0;测试样例2:ab ce 1 2,应输出:56;测试样例3:cpqejrrgp cpqejtrdg 9 9 输出:35064;测试样例4:a b 1 1 输出:0)。
牛客练习网址可测试:https://www.nowcoder.com/questionTerminal/f72adfe389b84da7a4986bde2a886ec3点击打开链接#include<iostream>
#include<string>
#include<math.h>
using namespace std;
int main() {
string str1, str2;
int len1, len2;
while (cin >> str1 >> str2 >> len1 >> len2) {
if (str1.length() < len2)
str1.append(len2 - str1.size(), 'a'-1);
if (str2.length() < len2)
str2.append(len2 - str2.size(), 'z'+1);
long long sum = 0;
int k = 0;
while (str1[k] == str2[k] && k < len2)
{
k++;
}
if (str1[k] < str2[k] && len1 <= len2)
{
for (int i = len1-1; i < len2; i++)
{
if (i == k)
{
if (k == len1 - 1 && k==len2-1)
sum += str2[k] - str1[k] - 1;
else
sum += str2[k] - str1[k];
}
else
sum += (str2[k] - str1[k] - 1)*pow(26, i - k);
}
k++;
for (int i = len1; i <= len2; i++)
{
//str[k]==str1[k]时的种数,注意当str1.size()<len1的时候
//后面的计算
for (int j = k; j < i; j++)
{
sum += ('z' - str1[j])*pow(26, i - j - 1);
}
//str[k]==str2[k]时的种数,注意当str2.size()>len2的时候
//后面的计算
for (int j = k; j < i; j++)
{
sum += (str2[j] - 'a')*pow(26, i - j - 1);
}
}
}
cout << sum << endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐