题目大意:
给你一个只有(、)、#、三种字符组成的字符串,#可以替换为至少为数量为1的“)”,问需要保证无论在字符串某个位子,从第一个字符到当前位子的“)”的数量都需要小于等于“(”的数量,并且#分配完"(“的数量加上原字符串上的“(”的数量需要和原字符串中的“)”数量相同才行,问一个可行分配解。如果没有输出-1.
思路:
1、首先我们先忽略掉#,然后看看原字符串会不会出现某个位子出现“)”数量大于“(”数量的情况,如果出现了,无论#如何分配,都是无解的情况。我们此时可以设定一个变量tmpp,每一次遇到(,tmpp++,遇到),tmpp--,如果出现了tmpp小于0的情况,就是上述说明的情况,输出-1。
2、当我们遇到一个#的时候,到底如何给#分配数量,因为后边的情况我们不清楚,那么我们贪心的想,直接将这个#赋一个)就行,因为首先这样做能够保证到当前位子,(的个数一定是大于等于)的数量的,其次我们可以留更多的)分配给后边的#。
3、那么我们确定一下贪心的思路:
①设定一个变量zuo,遇到一个左括号,zuo++;
②如果遇到一个右括号,zuo--;
③如果遇到了一个#,如果当前#不是最后一个#,那么我们赋值为1.遇到了最后一个#,我们再处理一下这个#后边的情况之后【因为要保证最终得到的字符串的左括号个数和右括号个数需要相同】,将需要赋的“)”的个数赋给这个#即可。
具体参考代码。
Ac代码;
#include<stdio.h>
#include<string.h>
using namespace std;
char a[1000000];
int ans[1000000];
int main()
{
while(~scanf("%s",a))
{
memset(ans,0,sizeof(ans));
int n=strlen(a);
int flag=0;
int zuo=0;
int cont=0;
int contz=0;
int tmpp=0;
for(int i=0;i<n;i++)
{
if(a[i]=='#')contz++;
if(a[i]=='(')tmpp++;
if(a[i]==')')
{
if(tmpp>0)
tmpp--;
else
{
tmpp=-1;break;
}
}
}
if(tmpp==-1)
{
printf("-1\n");
continue;
}
for(int i=0;i<n;i++)
{
if(a[i]=='(')
{
zuo++;
}
else if(a[i]==')')
{
if(zuo>0)
zuo--;
}
else
{
if(zuo>0)
{
if(cont+1!=contz)
{
ans[cont++]=1;
zuo--;
}
else
{
for(int j=n-1;j>i;j--)
{
if(a[j]==')')zuo--;
if(a[j]=='(')zuo++;
}
ans[cont++]=zuo;
zuo=0;
}
}
else flag=1;
}
}
if(flag==1||zuo!=0)
{
printf("-1\n");
}
else
{
int tag=0;
for(int i=0;i<contz;i++)
{
if(ans[i]==0||ans[i]<0)tag=1;
}
if(tag==1)
{
printf("-1\n");
}
else
{
for(int i=0;i<contz;i++)
{
printf("%d\n",ans[i]);
}
}
}
}
}