W
e
l
c
o
m
e
: )

题解:P10950 太鼓达人

分析

显然答案包含长度为 \(K\) 的所有 \(01\) 串,每个串和前一个的重叠长度为 \(K-1\),所以每个串对长度的贡献为 \(1\)

因此该串的长度为所有 \(01\) 串的个数,即 \(2^K\)


考虑第二个如何解决。

发现每个位置的状态只有 \(0\)\(1\),考虑爆搜。

显然直接搜的复杂度为 \(O(2^{2^K})\),不能通过本题。

考虑剪枝,如果搜索中当前的串不符合条件,那么直接返回。

这样就能通过本题。

Code

#include<bits/stdc++.h>
using namespace std;
#define maxn 100005

string ans, tmp;
bool vis[1<<12];

int to_int(string s)
{
    int ret=0;
    for(auto c:s) ret=(ret<<1)|(c^48);
    return ret;
}

bool chk(int k)
{
    tmp=ans+ans;
    int n=ans.size();
    memset(vis, 0, sizeof vis);
    for(int i=0;i<n;i++)
    {
        int r=to_int(tmp.substr(i, k));
        if(vis[r]) return 0;
        vis[r]=1;
    }
    return 1;
}

bool chk1(int k)
{
    tmp=ans;
    int n=ans.size();
    memset(vis, 0, sizeof vis);
    for(int i=0;i<n-k;i++)
    {
        int r=to_int(tmp.substr(i, k));
        if(vis[r]) return 0;
        vis[r]=1;
    }
    return 1;
}

void dfs(int p, int k)
{
    if(!chk1(k)) return;
    if(p==(1<<k)) 
    {
        if(chk(k)) cout<<ans, exit(0);
        return;
    }
    ans+='0';
    dfs(p+1, k);
    ans.pop_back();
    ans+='1';
    dfs(p+1, k);
    ans.pop_back();
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int k;
    cin>>k;
    cout<<(1<<k)<<' ';
    dfs(0, k);
}
posted @ 2024-09-24 16:30  Jimmy-LEEE  阅读(22)  评论(0)    收藏  举报