codeforces-#476B. Dreamoon and WiFi(dfs、二进制枚举)

          题目大意:给出两个字符串,一个是由“+“或”-“构成。第二个由于“+”、“-”、“?”构成,第二个字符串中的“?”可能是“+“或”-“。组成的字符串“+“的权值为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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值