BZOJ3033太鼓达人

第一问,1<<k,谁都看得出来。

毫无思路,暴搜,枚举每一个数列,Hash加map判断是否重复,拿到30,打表都打不出来。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
using namespace std;
const int p = 131;
int k, n, num;
int a[50000], b[50000];
unsigned long long op[50000], base[500];
map<unsigned long long, bool> mp;
bool check() {
    mp.clear();
    memset(op, 0, sizeof(op));
    for (int i = 1; i <= n; i++) op[i] = op[i - 1] * p + a[i];
    for (int i = k; i <= n; i++) {
        unsigned long long h = op[i] - base[k] * op[i - k];
        if (mp[h])
            return 0;
        mp[h] = 1;
    }
    return 1;
}
void dfs(int now) {
    if (now == n + 1) {
        //    for(int i=1;i<=n;i++)
        //        cout<<a[i];cout<<endl;
        if (check()) {
            for (int i = 1; i < n; i++) cout << a[i];
        cout<<1;
            exit(0);
        }
        return;
    }
    dfs(now + 1);
    a[now] = 1;
    dfs(now + 1);
    a[now] = 0;
}
int main() {
    scanf("%d", &k);
    base[0] = 1;
    for (int i = 1; i <= 300; i++) base[i] = base[i - 1] * p;
    n = 1 << k;
    printf("%d ", n);
    //    cout<<n<<endl;
    //    fgetc(stdin);
    dfs(1);
    return 0;
}
View Code

 

这搜索简直了。

其实有一些大模拟的意思。

dfs两个参量,x表示一个二进制数,也就是数出来长度为k的这个数,l表示当前填好了第几位。然后就是递归,标记某个数是否被填过,被填过直接return,没标记过先填上,把第l位填上x的末尾,然后将x的后k-1位填上一个1或0作为下一层的x递归搜索,最后输出ans数组即可。

当时听到这个东西,激动地抱了Soul三次,真是天才的打法,搜索竟然可以用到如此境地。

#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
int n,k;
int ans[50000];
bool vis[50000];
bool dfs(int x,int l){
    if(vis[x]) return 0;
    if(l==n+1) return 1;
    ans[l]=x&1;vis[x]=1;
    if(dfs(((x<<1)&((1<<k)-1)),l+1)) return 1;
    if(dfs(((x<<1|1)&((1<<k)-1)),l+1)) return 1;
    vis[x]=0;
    return 0;
}
int main(){
    scanf("%d",&k);
    n=1<<k;
    dfs(0,k);
    printf("%d ",n);
    for(int i=1;i<n;i++)
        printf("%d",ans[i]);
    putchar('1');
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Yu-shi/p/11177907.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值