codeforces 1153 D
C. Serval and Parenthesis Sequence
题意:给定由'(',')','?'组成的字符串,问是否能将其中的?全部换成'(‘,’)'使得字符串的任意非空真字串不构成正确的括号表达式,而整个字符串构成括号表达式,其中正确的括号表达式是指通过插入'1','+'能构成算术式。
思路:我们记'('为-1,')'为1,显然所有字串应满足前面的和<0,字串等于0的话就不满足字串不构成正确的括号表达式了,且整个字符串的和=0(题目可能出现'((((??'这样的数据,即无法构成正确的括号表达式的。我们用n1表示需要添加的'('的数量,n2表示要添加的')'的数量,利用贪心思想,将前n1个?全部换成'(',将剩下的?全换成')’。然后从头检查一遍即可
然后我wa在了代码的精简和处理上,这题处理好细节还是简单
在满足前缀不是正确的括号表达式而总字符串是正确的括号表达式,要满足第一个括号要与最后一个括号配对 (s[0]=='(" s[n-1]==')' ) //里面的括号不能把边上抢走了
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <string> 6 #include <map> 7 #include <iomanip> 8 #include <algorithm> 9 #include <queue> 10 #include <stack> 11 #include <set> 12 #include <vector> 13 //const int maxn = 1e5+5; 14 #define ll long long 15 #define MAX INT_MAX 16 #define FOR(i,a,b) for( int i = a;i <= b;++i) 17 18 using namespace std; 19 int n,ans1,ans2,woc; 20 string s; 21 int main() 22 { 23 // freopen("D:\\common_text\\code_stream\\in.txt","r",stdin); 24 // freopen("D:\\common_text\\code_stream\\out.txt","w",stdout); 25 26 cin>>n>>s; 27 if(n%2==1) 28 { 29 cout<<":("; 30 return 0; 31 } 32 if(s[0]==')'||s[n-1]=='(' ) 33 { 34 cout<<":("; 35 return 0; 36 } 37 for(int i=0;i<=n-1;++i) 38 { 39 if(s[i]=='(') 40 ans1++; 41 else if(s[i]==')') 42 ans2++; 43 } 44 if(ans1>n/2||ans2>n/2) //'('和')'数量分表不能过半 45 { 46 cout<<":("; 47 return 0; 48 } 49 ans1=n/2-ans1; 50 ans2=n/2-ans2; 51 for(int i=0;i<=n-1;++i) 52 { 53 if(s[i]=='?') 54 { 55 if(ans1>0) 56 { 57 ans1--; 58 s[i]='('; 59 } 60 else 61 { 62 ans2--; 63 s[i]=')'; 64 } 65 } 66 } 67 if(ans1!=0||ans2!=0) 68 { 69 cout<<":("; 70 return 0; 71 } 72 for(int i=0;i<=n-2;++i) //注意只是判断前缀满不满足该括号判断式子 73 { 74 if(s[i]=='(') 75 woc++; 76 else woc--; 77 if(woc==0) 78 { 79 cout<<":("; 80 return 0; 81 } 82 }
//以下两个可能多余o 83 if(n==2&&s[0]=='('&&s[1]==')') //因为下面的那个判断所以要对n==2特判 84 { 85 cout<<s; 86 return 0; 87 } 88 if(s[0]==')'||s[n-1]=='('||s[1]==')'||s[n-2]=='(') //防止里面把边上的抢走了 89 { 90 cout<<":("; 91 return 0; 92 } 93 cout<<s; 94 }