【题目】
笑脸
Description
durong经常使用telegram和外国友人聊天,有一天他的外国友人发给他一段字符串,里面只包含 '(' , ':' , ')' 这几个字符。
durong猜测 :)代表笑脸。 他现在想要恰好翻转一个前缀,使得笑脸最多。
翻转的定义是把 s[i...j]换成 s[j...i], 并且把 '(' 换成 ')', ')' 换成 '('。
比如 ":):((" 翻转以后是 ")):(:"
Input
第一行一个n代表字符串长度。
第二行一个只包含)(:三种字符的字符串。
1 <= n <= 2e5
Output
输出一个数,代表恰好翻转一个前缀以后的最多笑脸数。
Sample Input 1
10 :(:):(:):)
Sample Output 1
4
【思路】1存这位之前有多少个反着的笑脸,2之后有多少个正着的笑脸,ans=1+2;
特判1:当开头是':',而后面不是笑脸,而i之后又有一个')'可以凑出一个:),ans++
特判2:当i是':',i+1是')'的时候,翻转会拆散:),ans--
【代码】
#include<bits/stdc++.h>
using namespace std;
const int M=200005;
int main()
{
int n;
char a[M];
int sum1[M];
int sum2[M];
scanf("%d",&n);
scanf("%s",a);
int s=0;
for(int i=1;i<=n-1;i++)
{
if(a[i-1]=='('&&a[i]==':')
{
s++;
}
sum1[i]=s;
}
s=0;
for(int i=n-2;i>=0;i--)
{
if(a[i]==':'&&a[i+1]==')')
{
s++;
}
sum2[i]=s;
}
int ans=0;
for(int i=0;i<n-1;i++)
{
int aans=sum1[i]+sum2[i];
if(a[0]==':')
{
if(a[i]!=':'&&a[i+1]==')')
{
aans++;
}
}
else
{
if(a[i]==':'&&a[i+1]==')')
{
aans--;
}
}
ans=max(ans,aans);
}
ans=max(ans,sum1[n-1]);
ans=max(ans,sum2[0]);
printf("%d\n",ans);
}