第一问,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; }
这搜索简直了。
其实有一些大模拟的意思。
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; }