牛客网编程题
- 消消看
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 64M,其他语言128M
牛牛和牛妹最近迷上了新版消消看,该游戏规则如下:
在一个 串中,每一轮,玩家都可以选择一串连续相同字符进行消除,消除之后,左右两侧剩余的字符自动拼接,重新形成一个字符串。
例如:在 中,牛牛选择了第四个和第五个字符,它们连续且都是 ,满足消除条件,而当它们消除之后,左侧剩余的 和右侧剩余的 会拼接到一起,即:消除后剩余的 串为:
计分规则如下:消除了几个 就计几分。
直到消成空串时游戏结束。
对于一串全新的 串,由牛妹先手进行消除,两个人都以最优策略且以得分高为目标进行消除,请问最后,哪个人的得分会比较高?
- 输入描述:
本题为多组测试数据,第一行输入一个正整数 ,代表测试数据组数。
对于每组测试数据,一行输入一个长度不超过 的 串,代表初始形态。
- 输出描述
对于每组测试数据,如果牛妹得分高,则在第一行输出 ,第二行输出一个分数代表牛妹比牛牛高几分;如果牛牛得分高,则在第一行输出 ,第二行输出一个分数代表牛牛比牛妹高几分;如果两个人分数相同,则只需要在一行输出 .
- 输入例子
2
111111
111011
- 输出例子
Niumei
6
Niumei
1
- 分析
- 先遍历字符串找到第一个相邻相同的子串,作为牛妹的子串,并根据子串是0还是1返回一个权重;
- 在原串中将该子串删除,再循环找下一个相同的子串,作为牛牛的子串,并返回权重;
- 如果没有相邻相同的子串,则将串中第一个字符返回,直到为空串;
- 牛妹得分为权重*子串长度之和,牛牛的也是;
- 输入接口用一个vector来装字符串,并遍历vector找子串;
- 具体实现
(1) 找寻子串函数
string xiaosingle(string s,int &rate){
stringstream x_str;
const char* pt = s.c_str();
char tmp = *pt;
if(s.size() == 1){
if(s.c_str()[0] == '0')
rate=0;
else
rate = 1;
x_str << s.c_str()[0];
return x_str.str();
}
for(size_t i=1;i<s.size();i++)
{
if(pt[i] == pt[i-1])
{
if(pt[i] == '0')
rate = 0;
else
rate = 1;
if(x_str.str().empty())
{
x_str << pt[i-1] << pt[i];
}
else
x_str << pt[i];
}
else{
if(x_str.str().empty())
continue;
else{
break;
}
}
}
if(x_str.str().empty()){
if(s.c_str()[0] == '0')
rate=0;
else
rate = 1;
x_str << s.c_str()[0];
}
return x_str.str();
}
(2) 输入接口及得分
void xiaoxiaokan(const string s)
{
string ss = s,s1,s2;
int n_niumei=0,n_niuniu=0;
int rate=0;
int n1=0,n2=0;
while(ss.size() != 0){
s1.clear();s2.clear();
s1 = xiaosingle(ss,rate);
n1 = ss.find(s1);
ss.erase(n1,s1.size());
n_niumei += s1.size()*rate;
if(ss.empty()){
break;
}
else{
s2 = xiaosingle(ss,rate);
n2 = ss.find(s2);
ss.erase(n2,s2.size());
n_niuniu += s2.size()*rate;
}
}
if(n_niumei > n_niuniu){
cout << "Niumei" << "\n" << n_niumei-n_niuniu << endl;
}
else if(n_niumei == n_niuniu){
cout << "Draw" << endl;
}
else{
cout << "Niuniu" << "\n" << n_niuniu-n_niumei << endl;
}
}
void xiaoxiaole(const std::vector<string> str)
{
for(auto s : str){
xiaoxiaokan(s);
}
}
int main(int argc,char** argv)
{
int n;
std::vector<string> s_v;
cin >> n;
for(int i=0;i<n;i++){
string str;
cin >> str;
s_v.push_back(str);
}
xiaoxiaole(s_v);
return 0;
}
(3) 测试结果
(4) 问题
本解法耗时77ms,占用内存较大,后期会试着进行优化,但奇怪的是本机上能够通过的例子,而且想了很多边界案例,比如输入1,0,10,01,00,11,101,010之类的,都能通过,但在牛客网上却通过不了,希望有知道的大佬可以指点迷津,万分感谢!