codeforces 1095 E. Almost Regular Bracket Sequence

题目:http://codeforces.com/contest/1095/problem/E

题意:给你一个只有( )的字符串,问只改动一个括号的方向,有多少种改法使字符串合法

思路:从前往后和从后往前扫一次,考虑该字符左边的 ( 数目记为x,右边的 )数目记为 y
当该字符为 ( 并且 x-y=-1时 ans++,相当于左边多了一个左括号,只需要将当前改变就可以。
同意该字符为 ) x-y==-1 ans++;
还有当在字符左边出现 ) 数目更多时,或者右边( 更多时,那么该串后面就都要记录为不合法
(当时自己这个地方没记录导致wa,因为后面可能会出现相反符号又使cnt变为正,那么就出错了)

#include<bits/stdc++.h>
#define fi first
#define se second
#define FOR(a) for(int i=0;i<a;i++)
#define sc(a) scanf("%d",&a)
#define show(a) cout<<a<<endl;
#define show2(a,b) cout<<a<<" "<<b<<endl;
#define show3(a,b,c) cout<<a<<" "<<b<<" "<<c<<endl;
using namespace std;

typedef long long ll;
typedef pair<int, int> P;
typedef pair<P, int> LP;
const ll inf = 1e17 + 10;
const int N = 1e6 + 10;
const ll mod = 998244353;

map<string, int>ml;



ll b[N], vis[N], po[N], num[N], t, n, m, x, y, k, a[N];
ll ex, ey, cnt, ans, sum, flag;
ll dist[N];
ll dp[N];

vector<int> v[N];
map<int, int> mp;
priority_queue<P> q;
priority_queue<P> tq;


int main()
{
	ios::sync_with_stdio ( false );
	cin.tie ( 0 );

	cin>>n;
	string s;
	cin>>s;
	for(int i=0;s[i];i++)
	{
		a[i]=cnt;
		if(s[i]=='(') cnt++;
		else cnt--;
		if(a[i-1]<0) a[i]=-1;
	}
	cnt=0;
	for(int i=n-1;i>=0;i--)
	{
		b[i]=cnt;
		if(s[i]==')') cnt++;
		else cnt--;
		if(b[i+1]<0) b[i]=-1;
	}
	for(int i=0;s[i];i++)
	{
		if(a[i]<0&&b[i]<0) return cout<<0<<endl,0;
		num[i]=a[i]-b[i];
		//show2(a[i],b[i])
		if(s[i]=='('&&num[i]==1&&a[i]>=0&&b[i]>=0) ans++;
		if(s[i]==')'&&num[i]==-1&&a[i]>=0&&b[i]>=0) ans++;
	}
	cout<<ans<<endl;




}

猜你喜欢

转载自blog.csdn.net/weixin_42640692/article/details/86547460