题目大意:给出两个字符串,一个是由“+“或”-“构成。第二个由于“+”、“-”、“?”构成,第二个字符串中的“?”可能是“+“或”-“。组成的字符串“+“的权值为1,”-“的权值为-1.问组成的权值和与第一个相等的概率是多少?
解题思路:第一个权值和知道,第二个知道部分,“?”可能是“+“或”-“两种情况,就想到用二进制枚举来推,推了下用例是对的,就敲了,可是到现在也没找到在那个地方出问题了,与正确答案对比10个问号的时候数量居然少了,很不服气呀。不过换用递归的dfs写法简洁快速多了。详见code.
题目来源:http://codeforces.com/contest/476/problem/B
一直纠结没过的 code:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int MAXN = 10+5;
int ans1,ans2,cnt,ans;
char str[MAXN];
int main(){
//freopen("input.txt","r",stdin);
while(gets(str)){
ans=0;ans1=0;ans2=0;cnt=0;
int len=strlen(str);
for(int i=0;i<len;++i){
if(str[i]=='+') ans1++;
else ans1--;
}
gets(str);
for(int i=0;i<len;++i){
if(str[i]=='+') ans2++;
else if(str[i]=='-') ans2--;
else cnt++;
}
if(cnt==0){
if(ans1==ans2)
printf("%.10f\n",(double)1);
else
printf("%.10f\n",(double)0);
continue;
}
int tmp=pow(2,cnt);
for(int i=0;i<tmp*2;++i){
int m=ans2;
if(i==0) m--;
for(int j=i;j>0;j/=2){
if(j&1) m++;
else m--;
}
if(m==ans1) ans++;
}
printf("%.10f\n",ans*1.0/tmp);
}
return 0;
}
dfs code:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 10+5;
char str[MAXN];
int ans1,ans2;
int sum[MAXN*2];
void dfs(int pos,int num){
if(pos==strlen(str)){
sum[num+10]++;
ans2++;
return ;
}
if(str[pos]=='+')
dfs(pos+1,num+1);
else if(str[pos]=='-')
dfs(pos+1,num-1);
else{
dfs(pos+1,num+1);
dfs(pos+1,num-1);
}
}
int main(){
//freopen("input.txt","r",stdin);
while(gets(str)){
ans1=0;ans2=0;
int len=strlen(str);
for(int i=0;i<len;++i){
if(str[i]=='+') ans1++;
else ans1--;
}
gets(str);
dfs(0,0);
printf("%.10f\n",sum[ans1+10]*1.0/ans2);
}
return 0;
}