2016网易游戏 游戏研发岗 在线笔试解题报告
A题 Amusing Digits
问题描述
给定一个数串,从中选出尽可能多的“9706”子串,要求每个digit的相对先后顺序不变且每个digit只能用一次,问最多可以选出多少个9706子串。
样例输入
4
6097
97069706
997776600069
123901370997606
样例输出
0
2
1
2
解题思路
通过分析,本题满足使用贪心策略。考虑数串9799706,若选择数字9时,跳过第一个9选择第二个9,将会导致第一个数字7无法匹配,因此每次选择数字9时,优先最靠前没使用过的,可以达到最优。同理其他数字也满足该原则。
根据以上分析,容易得到思路:遍历整个数串,选取最靠前的9;若找到9,再选取9以后最靠前的7;依次同理把0和6找到。但很可惜,这样的解法是要TLE的,该方法的复杂度为O((k+1)*n),k为答案,n为(去掉其他无关数字后的)数串长度。构造输入99..977..700..066..6
,每个数字都有10000个,这样程序就gg了。
换一种思路,考虑到每次遍历都是要选取最靠前的数字,而下一个候选数字又必须在前一个数字的后面。只考虑数字9和数字7,有效子串的个数实际上取决于有多少个7,每个7的前面都恰好有一个9和它对应。把数字0和6考虑进去同理,所以最终有效子串的个数,取决于有多少个6,每个6的前面都恰有一个0和它对应;这些0中的每一个,前面都恰有一个7和他对应……时间复杂度为O(n)。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int T;
cin >> T;
while (T--)
{
string s;
cin >> s;
int sz = s.length();
int c9, c7, c0, c6;
c9 = c7 = c0 = c6 = 0;
for (int i = 0; i < sz; i++)
{
switch(s[i])
{
case '9': c9++; break;
case '7': if (c7 < c9) c7++; break;
case '0': if (c0 < c7) c0++; break;
case '6': if (c6 < c0) c6++; break;
}
}
cout << c6 << endl;
}
return 0;
}
B题 Best Compression Algorithms
问题描述
给定一个字符串,仅有圆括号,大写字母和数字组成。字串的数字表示它前面的字母或者括号中的模式的个数,如A2表示AA,(BC)3表示BCBCBC;允许复合,如(A3(BC)2)2表示AAABCBCAAABCBC。求给定字符串展开后的长度(即不包含数字和括号的表示的长度)。
样例输入
4
(AA)2A
((A2B)2)2G
WANGYI
A2BC4D2
样例输出
5
13
6
9
解题思路
该题的嵌套括号,可以联想到使用栈来保存每一层级的字符个数缓存。考虑变量k为某一层括号中的临时字符个数统计,初始为0,若遇到非括号嵌套的字符直接累加;若遇到左括号,将当前k的值压入栈,对k置0,统计下一层括号中字符个数;若遇到右括号,则将栈顶元素弹出(表示上一层字符个数的缓存),累加到k。
#includ