题目描述
题目:https://vjudge.net/problem/CodeForces-1214C
思路分析
这道题很容易让我们想到我们经典的括号匹配问题。当时,我们是用栈的思想,或者模拟栈+1、-1解决的。但是这道题有点不同:它问的是能否通过移动一个括号,令这个序列变成合法的序列。
一开始,我按照往常的做法:+1、-1,当检测到不合法的时候就计数,最后按照计数结果判断输出Yes还是No:
错误代码:
#include <iostream>
using namespace std;
int main()
{
int n;
string a;
cin>>n;
if(n==0)
{
cout<<"Yes"<<endl;
return 0;
}
cin.get();
getline(cin,a);
int cnt=0;
for(int i=0;i<a.size();i++)
{
cnt+=(a[i]=='(');
}
if(cnt!=n-cnt)
{
cout<<"No";
return 0;
}
// cout<<a<<endl;
int pos=0;
int counter=0;
for(int i=0;i<a.size();i++)
{
if(a[i]=='(')
{
pos--;
}
else if(a[i]==')')
{
pos++;
}
if(pos>0)
{
counter++;
}
}
if(counter>=2||pos!=0)
{
cout<<"No"<<endl;
}
else
{
cout<<"Yes"<<endl;
}
return 0;
}
因此一直卡在test11处。后来,看了大佬们的写法,发现大佬们都是这样写的:
for ( int i=1 , i<=n , i++ )
if ( s[i] == '(' ) ++ cnt ;
else { if ( cnt ) -- cnt ; else ++ num ; }
if ( cnt + num > 2 ) puts ("No") ; else puts ("Yes") ;
想法就是计算多余的(数(cnt)和多余的)数(num),然后看符不符合要求。
后来我想到了一组数据,问题也就迎刃而解了
4
)()(
若按照+1、-1写,那么,它不会看到中间()是匹配的,会认为有)(和)(两处不匹配导致错误。
希望对各位有所帮助
完整代码
#include <iostream>
using namespace std;
int main()
{
int n;
string a;
cin>>n;
if(n==0)
{
cout<<"Yes"<<endl;
return 0;
}
cin.get();
getline(cin,a);
int cnt=0;
for(int i=0;i<a.size();i++)
{
cnt+=(a[i]=='(');
}
if(cnt!=n-cnt)
{
cout<<"No";
return 0;
}
// cout<<a<<endl;
int pos=0;
int counter=0;
for(int i=0;i<a.size();i++)
{
if(a[i]=='(')
{
pos++;
}
else
{
if(pos)
{
--pos;
}
else
{
counter++;
}
}
}
if(counter+pos>2)
{
cout<<"No"<<endl;
}
else
{
cout<<"Yes"<<endl;
}
return 0;
}