dfs-Bit Compression

链接:https://www.nowcoder.com/acm/contest/145/C
来源:牛客网
 

Bit Compression

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld

题目描述

A binary string s of length N = 2n is given. You will perform the following operation n times :

- Choose one of the operators AND (&), OR (|) or XOR (^). Suppose the current string is S = s1s2...sk. Then, for all , replace s2i-1s2i with the result obtained by applying the operator to s2i-1 and s2i. For example, if we apply XOR to {1101} we get {01}.

After n operations, the string will have length 1.

There are 3n ways to choose the n operations in total. How many of these ways will give 1 as the only character of the final string.

输入描述:

The first line of input contains a single integer n (1 ≤ n ≤ 18).

The next line of input contains a single binary string s (|s| = 2n). All characters of s are either 0 or 1.

输出描述:

Output a single integer, the answer to the problem.

示例1

输入

复制

2
1001

输出

复制

4

说明

The sequences (XOR, OR), (XOR, AND), (OR, OR), (OR, AND) works.

题意在map那篇博客里已经说过了,这题也可用dfs做,map的做法不好想但是想出来之后代码好实现,dfs思路好想,但是代码不好实现。dfs怎么想?就是第一次可以从三个里面选一个,选完之后又可以从三个操作符里选一个,就样深搜下去。

然后自己YY了一发。

WA的代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=270000;
char s[maxn];
int FangAn;
int n;
int tmp1[maxn],tmp2[maxn],tmp3[maxn];
void dfs(int d[],int ceng,int logal,int k){
    int c;
    int cnt=0;
    int flag=0;
    if(ceng==n)
    {
        if(logal==1)
        {
            for(int i=1;i<=k/2;i++)
            {
                d[++cnt]=(d[2*i-1]^d[2*i]);
            }
        }
        else if(logal==2)
        {
            for(int i=1;i<=k/2;i++)
            {
             d[++cnt]=(d[2*i-1] | d[2*i]);
            }
        }
        else
        {
            for(int i=1;i<=k/2;i++)
            {
              d[++cnt]=(d[2*i-1] & d[2*i]);
            }
        }
        if(d[1]==1)
        {
            //cout<<"FangAn"<<FangAn<<endl;
            FangAn++;
        }
        //cout<<d[1]<<"  %%%%  "<<endl;
         return ;
    }
    if(logal==1){
        for(int i=1;i<=k/2;i++){
            d[++cnt]=(d[2*i-1]^d[2*i]);
            cout<<cnt<<" "<<d[cnt]<<" $$ "<<endl;
           if(d[cnt]==1)
            flag=1;
        }
        c=ceng;
        c+=1;
        if(flag==0)
        {return;}
        dfs(d,c,1,cnt);
        dfs(d,c,2,cnt);
        dfs(d,c,3,cnt);
    }
    else if(logal==2){
        for(int i=1;i<=k/2;i++){
             d[++cnt]=(d[2*i-1] | d[2*i]);
             cout<<cnt<<" "<<d[cnt]<<" YY "<<endl;
             if(d[cnt]==1)
                flag=1;
        }
         //ceng+=1;
         c=ceng;
         c+=1;cout<<c<<" "<<flag<<" TT "<<endl;
         if(flag==0)
            return;
         dfs(d,c,1,cnt);cout<<FangAn<<" QQ "<<endl;
         dfs(d,c,2,cnt);cout<<FangAn<<" WW "<<endl;
         dfs(d,c,3,cnt);cout<<FangAn<<" RR "<<endl;
    }
    else{
          for(int i=1;i<=k/2;i++)
          {
              cout<<d[2*i-1]<<" "<<d[2*i]<<" ||| "<<endl;
             d[++cnt]=(d[2*i-1] & d[2*i]);
             cout<<cnt<<" "<<d[cnt]<<" +++ "<<endl;
             if(d[cnt]==1)
                flag=1;
          }
         c=ceng;
         c+=1;
         if(flag==0)
            {return;}
         dfs(d,c,1,cnt);
         dfs(d,c,2,cnt);
         dfs(d,c,3,cnt);
    }
}
int main()
{
    FangAn=0;
    scanf("%d",&n);
    int length=pow(2,n);
    scanf("%s",s);
    for(int i=0;i<length;i++){
        if(s[i]=='0') tmp1[i+1]=0,tmp2[i+1]=0,tmp3[i+1]=0;
        else    tmp1[i+1]=1,tmp2[i+1]=1,tmp3[i+1]=1;
    }
    dfs(tmp1,1,1,length);cout<<FangAn<<" ### "<<endl;
    dfs(tmp2,1,2,length);cout<<FangAn<<" ^^^ "<<endl;
    //dfs(tmp3,1,3,length);cout<<FangAn<<" *** "<<endl;
    cout<<FangAn<<endl;

}


一开始就用了一个tmp,发现运行完主函数里的dfs(tmp,1,1,length),再输出tmp一看tmp变了,但是tmp不能变,感觉tmp不会变啊,只是让tmp去运行dfs,不知道怎么弄得,好吧既然变了我就用三个tmp来弄,这个小bug改完了。发现dfs里三个dfs摞在一起的那三个语句,执行完第一个d数组就变了,但是d数组也不能变。所以虽然是那样想,但是代码不是按想的思路走的。

所以想办法不要让d数组改变。

AC代码

#include<bits/stdc++.h>
using namespace std;
char dp[20][300000];
long long ans;
char op(int k,char a,char b){
    int aa=a-'0';
    int bb=b-'0';
    if(k==0) return (aa&bb)+'0';
    if(k==1) return (aa|bb)+'0';
    if(k==2) return (aa^bb)+'0';
    return '0';
}
void dfs(int cur){
    if(cur==0){
        if(dp[cur][0]=='1'){
            ans++;
        }
        return;
    }
    for(int k=0;k<3;k++){
        int cnt=0;
        for(int i=0;i<(1<<cur);i+=2){
            char ch=op(k,dp[cur][i],dp[cur][i+1]);
            if(ch=='1') cnt++;
            dp[cur-1][i/2]=ch;
        }
        if(cnt==0) continue;
        dfs(cur-1);
    }
}
int main(){
    int n;
    scanf("%d",&n);
    scanf("%s",dp[n]);
    ans=0;
    dfs(n);
    printf("%lld\n",ans);
}

猜你喜欢

转载自blog.csdn.net/qq_37891604/article/details/81568206