2018 牛客多校第七場 C Bit Compression (DFS+剪枝)

https://www.nowcoder.com/acm/contest/145/C

 

題意:給你一個n,再給你一個長度爲2的n次方的01串。每次字符串可以選擇三種操作:& | ^。選擇之後,相鄰的字符按這個操作合併:比如 1101 選擇^  則   1^1=0  0^1=1; 然後字符串就變成了01。繼續操作直到剩餘一個字符。問你最後只剩一個1的方法總數有多少種。

思路:

直接爆搜會TLE,注意剪枝,如果全爲0的,這三種操作怎麼操作都不可能是1,所以直接停止。

保存每次操作的答案可以模仿線段樹一樣,最底下的一層是原串,然後一層一層網上遞歸,最後判斷根節點是否爲1,這樣就不會破壞原來的字符串了。

 

代碼:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=1e6+10;
char c[maxn];
int t[maxn*4];
int ans;
void dfs(int n)
{
    if(n==-1)
    {
        if(t[1]==1)
        {
            ans++;
        }
        return;
    }
    int k=1<<n;
    for(int i=0;i<3;i++)
    {
        int zz=0;
        for(int j=0;j<k;j++)
        {
            int te=j+k;
            if(i==0)
            {
                t[te]=t[te*2]|t[te*2+1];
            }
            if(i==1)
            {
                t[te]=t[te*2]^t[te*2+1];
            }
            if(i==2)
            {
                t[te]=t[te*2]&t[te*2+1];
            }
            if(!t[te])zz++;
        }
        if(zz==k)continue;
        dfs(n-1);
    }
}
int main()
{
    int n;
    scanf("%d",&n);
    scanf("%s",c);
    int k=1<<n;
    for(int i=0;i<k;i++)
    {
        t[i+k]=c[i]-'0';
    }
    ans=0;
    dfs(n-1);
    printf("%d\n",ans);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章