2018网易校招运营开发工程师编程第一题
由于之前准备不充分,没有做大量的编程练习,在实际编程过程中算法设计出现疏漏,最终导致结果没有AC。
题目很简单,字符串编码问题。 一个长度不超过6的字符串,内部不会重复且所有字母已经按照字典序排好。接下来按照字典序从短到长对这些字符串进行编码,接下来让你输入一个字符串,输出对应的编码即可。 eg: a为1,z为26,ab为27,az为51,bc为52。。。
思路和之前在牛客网做过的编码题类似,跳过某些的字符串,直到定位到该字符串为止。
举个例子:
字符串为forx。它跳过了所有的长度为1,长度为2,长度为3的字符串,以及所有长度为4的字符串中ae开头的,fgfn开头的,fop~foq开头的字符串。最后检查从fors到forx的序号就行了。
刚开始思路出了点问题,跳过的过程中,我跳过了fa~fn这类包括了fa但是不可能出现的情况,结果导致最后的算法出来的结果并不如意,并且一直很异常。直到笔试结束,我也没及时跳出这个坑。
笔试结束后我重新审查我的算法才发现了这个bug,并最终解决。最终的代码如下:
1#include <iostream>
2using namespace std;
3int C_a_b(int a, int b){
4 if(b == 0) return 0;
5 int result = 1, num = a;
6 while(num>(a-b))
7 result *= num--;
8
9 num = b;
10
11 while(num>0) result /= num--;
12 return result;
13}
14int main()
15{
16 int N, len, number = 0;
17 string input_str;
18 cin >> N;
19 while(N--){
20 number = 0;
21 cin >> input_str;
22 len = input_str.length();
23
24 if(len == 1){
25 cout << input_str[0] -'a' + 1 << endl;
26 continue;
27 }
28
29 // 跳过所有长度小于该字符串的数目
30 for(int i = 1; i<len; ++i){
31 number += C_a_b(26, i);
32 }
33
34 // 逐次跳过,eg:forx,首先跳过a开头的到e开头的所有长度为4的字符串(C_25_3累加到C_21_3)
35 // 然后跳过fg开头到fn的所有长度为3的字符串(C_19_2累加到C_12_2)
36 // 然后跳过fop到foq(C_10_1累加到C_9)
37 for(int i = len-1, j = 25; i>0; --i){
38 for(; j != 'z' - input_str[len-i-1]; j--){
39 number += C_a_b(j, i);
40 }
41 j--;
42 }
43 // 将最后一位的值算出来。eg:forx,则先算出从fors开始计数到forx时,对应的值
44 number += (input_str[len-1] - input_str[len-2]);
45
46 cout << number << endl;
47 }
48}
目测应该没够ac。特殊测试样例为a,z,ab,az,bc(和前面样例差一),bz,yz,abc(和前面样例差一),abz,acd(和前面样例差一)