/*ACMer:MDK 时间居然是最慢的一个。。。汗。 UserID: MDKSubmit time: 2011-04-30 17:29:16Language: C++Length: 2061 Bytes.Result: Accepted */ #include<stdio.h> #include<iostream> #include<limits.h> #include<string.h> #include<math.h> #include<vector> #include<algorithm> #include<set> #include<map> #include<stack> #define MAXN 2000 using namespace std; char c[20],a[20]; string ku="0000000000000000000"; void fun(int n,int r){ if(n){ fun(n/r,r); ku+=n%r>9? n%r-10+'A':n%r+'0'; } } int next(int j) { for(int i = j+1;i<strlen(a);i++) if(a[i]!=' ') { //cout<<"next(j) :"<<i<<endl; return i; } return MAXN; } int OK() { for(int i = 0;i<strlen(a);i++) { for(int j = 0 ;j<strlen(a);j++) { if(a[j]=='('&&next(j)!=MAXN&&a[next(j)]==')') { a[j]=' '; a[next(j)]=' '; } } } for(int i = 0;i<strlen(a);i++) if(a[i]!=' ') return 0; return 1; } int main() { while(cin>>c) { int n=0,d[20],flag=0,num=0; for(int i = 0;i<strlen(c);i++) { if(c[i]=='?') d[n]=i,n++; } if(n==0) cout<<"-0"<<endl; else { for(int i = 0;i<pow(2,n);i++) { fun(flag++,2); strcpy(a,c); for(int j = 0;j<n;j++) { if(ku[ku.length()-1-j]=='0') a[d[j]]='('; if(ku[ku.length()-1-j]=='1') a[d[j]]=')'; } if(OK()) { num++; } ku="000000000000000000"; } cout<<num<<endl; } } }
主要思想是枚举,很是笨的方法,丑陋的代码贴着了.
找到了一个把所有排列情况枚举出来的方法,主要原理是用进制的限制。
string ku="0000000000000000000";
void fun(int n,int r){ //10进制对各个进制的转换,代码之精简非常感谢我的朋友LY
if(n){
fun(n/r,r);
ku+=n%r>9? n%r-10+'A':n%r+'0';
}
}
这里就是采用了二进制的数,因为只有“(”和“)”两种枚举情况,几种情况就是几进制的。
然后就是hash:
1 fun(flag++,2);
2 strcpy(a,c);
3 for(int j = 0;j<n;j++)
4 {
5 if(ku[ku.length()-1-j]=='0')
6 a[d[j]]='(';
7 if(ku[ku.length()-1-j]=='1')
8 a[d[j]]=')';
9 }
接着就是判断是否满足条件的函数了,easy了。
排列数的枚举。