/*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了。
排列数的枚举。
浙公网安备 33010602011771号