标签:题意 pac 影响 memset false ons return const name
题意:给出括号序列s,其中有‘?‘表示可以为‘(‘或‘)‘.
|s|<=1e6,问将这些‘?‘代替后,s是否合法,若合法 是否有多解?
首先:把已经匹配的丢出去,不影响序列的合法性
则 维护前缀i ‘(‘最多和最少未匹配的个数,对后缀i维护‘)‘最多和最少未匹配的个数 (还剩个数)
当max[i]<0 说明某个‘(‘或‘)‘不够匹配为无解.
假如后缀i最少有x个‘)‘,则前缀i-1最少要有x个‘(‘ 后缀i最多有y个‘)‘ 前缀i-1‘(‘个数不多于y
则前面左括号的范围就为[x,y]若y-x+1>=2,则前缀i-1左括号有多种选择,后面右括号对应也有多种选择,则有多解
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair<ll,ll> ii; const int N=2e6+20; const ll mod=1e9+7; char s[N]; int f[N],g[N],a[N],b[N]; int main() { while(scanf("%s",s+1)!=EOF) { int n=strlen(s+1); if(n%2) { puts("None"); continue; } bool flag=true,mk=false; memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); memset(f,0,sizeof(f));//×?éù memset(g,0,sizeof(g)); for(int i=1;s[i];i++) { f[i]+=f[i-1]; g[i]+=g[i-1]; if(s[i]==‘(‘) f[i]++,g[i]++; if(s[i]==‘)‘) f[i]--,g[i]--; if(s[i]==‘?‘) f[i]--,g[i]++; if(f[i]<0) f[i]=1;//‘?‘2??ü±? if(g[i]<0) flag=false; } for(int i=n;i>=1;i--) { a[i]+=a[i+1],b[i]+=b[i+1]; if(s[i]==‘(‘) a[i]--,b[i]--; if(s[i]==‘)‘) a[i]++,b[i]++; if(s[i]==‘?‘) a[i]--,b[i]++; if(a[i]<0) a[i]+=2; if(b[i]<0) flag=false; if(min(b[i],g[i-1])-max(a[i],f[i-1])+1>=2) mk=true; } if(flag==false) puts("None"); else { if(mk) puts("Many"); else puts("Unique"); } } return 0; }
HDU 4915 Parenthese Sequence 思维+模拟
标签:题意 pac 影响 memset false ons return const name
原文地址:http://www.cnblogs.com/HIKARI1149/p/7252880.html