看了一下百度上还没有这题的题解,那我来发一个吧,仅以镜鉴,或者纪念。
题目如下:
A bracket sequence is called regular if it is possible to obtain correct arithmetic expression by inserting characters + and 1 into this sequence. For example, sequences (())(), () and (()(())) are regular, while )(, (() and (()))( are not. Let’s call a regular bracket sequence “RBS”.
You are given a sequence s of n characters (, ), and/or ?. There is exactly one character ( and exactly one character ) in this sequence.
You have to replace every character ? with either ) or ( (different characters ? can be replaced with different brackets). You cannot reorder the characters, remove them, insert other characters, and each ? must be replaced.
Determine if it is possible to obtain an RBS after these replacements.
Input
The first line contains one integer t (1≤t≤1000) — the number of test cases.
Each test case consists of one line containing s (2≤|s|≤100) — a sequence of characters (, ), and/or ?. There is exactly one character ( and exactly one character ) in this sequence.
Output
For each test case, print YES if it is possible to obtain a regular bracket sequence, or NO otherwise}.
You may print each letter in any case (for example, YES, Yes, yes, yEs will all be recognized as positive answer).
Example
input |
---|
5 () (?) (??) ??() )?(? |
output |
YES NO YES YES NO |
翻译如下:
如果在括号序列中插入字符+和1可以获得正确的算术表达式,则该序列称为正则序列。例如,序列 (())(), () 和 (()(())) 是常规,而)((()和(()))(不是。让我们把一个常规的括号序列称为“RBS”。
给定一个由n个字符组成的序列s(,)和/或?在这个序列中恰好有一个字符(并且恰好有一个字符)。
你必须替换每个字符?用)或((不同的字符?可更换不同的托架)。您不能重新排列字符,删除它们,插入其他字符,每个?必须更换。
确定在这些替换之后是否有可能获得RBS。
输入
第一行包含一个整数t(1≤t≤1000)-测试用例的数量。
每个测试用例由一行包含s(2≤|s|≤100)-字符序列(,),和/或?在这个序列中恰好有一个字符(并且恰好有一个字符)。
输出
对于每个测试用例,如果有可能获得一个正规的括号序列,则打印YES,否则不打印}。
你可以在任何情况下打印每一个字母(例如:YES, YES, YES, YES都会被认为是肯定的回答)。
分析:
刚开始看的话,会感觉这道题很复杂,因为无法确定哪个左括号对应哪个右括号,会不会内层括号对应到外层去,再加上还有未知的?也会影响到左括号和右括号的对应关系。
但是目前我们可以确定的是,第一个符号一定是左括号,最后一个符号一定是右括号,并且所有字符的个数一定是偶数。
按照这个思路继续下去,我们其实不需要知道哪个对应哪个,因为我们只需要确定它能够完成这个对应即可。也就是说,我们只要确保括号加上问号最终能组成全部都完整的()
,至于?
和(
和)
的改变会使括号的对应关系改变……不管它们怎样互相对应,至少他们能够组成完整的()
。
因此,可以写出如下代码:
#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
int t,len,count1,count2,count3,cha,i;
char s[110];
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
len=strlen(s);
if(len%2==0) //符号总个数一定为偶数
{
if((s[0]=='('||s[0]=='?')&&(s[len-1]==')'||s[len-1]=='?')) //符号首位和末尾的括号对应关系
{
count1=0; //统计(的个数
count2=0; //统计)的个数
count3=0; //统计?的个数
for(i=1;i<len-1;i++) //len-1是因为字符数组从0开始
{
if(s[i]=='(')
count1++;
else if(s[i]==')')
count2++;
else if(s[i]=='?')
count3++;
}
cha=fabs(count1-count2); //计算两种括号之间相差的个数
if(count3>=cha) //如果?足够弥补所差,那么弥补完所差之后,剩余的?个数应为偶数
{
count3=count3-cha;
if(count3%2==0)
printf("YES\n");
else
printf("NO\n");
}
else //如果?不够所差,则直接输出NO
printf("NO\n");
}
else //首位符号为)或末尾位为(都直接输出NO
printf("NO\n");
}
else //符号总个数为奇数,直接输出NO
printf("NO\n");
}
return 0;
}
成功 Accepted