填坑……链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3033
题意:长度为定长的$0-1$串构成一个环形长串,这个长串中每一个元素开始的子串都不相同,输出长串的最长长度和最小字典序解。
看到了数据范围就想到了暴搜……但是考虑到我在刷图论的题(⊙﹏⊙)b,再加之仔细分析之后状态数会达到$2^2048$,难以承受。
但是这么放着也不是个事……于是我就想打个表找规律……结果暴搜搜$11$也瞬间出解……于是交了上去,然后,$A$了……
但是为什么暴搜会这么快呢……我们把每个子串对应的状态看做一个点,显然每个点都会由两个状态转化而来,每个点又会转化为两个新状态。入度和出度相等,这就变成了欧拉回路问题,然后时间复杂度就是$O(n)$的了……

1 #include<iostream> 2 #include<cstdio> 3 #include<string> 4 #include<algorithm> 5 using namespace std; 6 string s,ans; 7 int n,len,length; 8 bool exist[1<<11]; 9 int tmp; 10 bool check(int add) 11 { 12 int x=0; 13 for(int i=s.size()-n+1;i<s.size();i++)x=(x<<1)|(s[i]-'0'); 14 x=(x<<1)|add; 15 if(!exist[x]) 16 { 17 tmp=x; 18 exist[x]=1; 19 return 1; 20 }return 0; 21 } 22 bool t; 23 void dfs(int num) 24 { 25 if(num>length) 26 { 27 cout<<length<<" "; 28 int cha=s.size()-length; 29 while(cha--)s.erase(s.end()-1); 30 cout<<s;t=1;exit(0); 31 } 32 if(s.size()>length) 33 { 34 if(check(0)) 35 { 36 int l=tmp; 37 s+='0'; 38 dfs(num+1); 39 s.erase(s.end()-1); 40 exist[l]=0; 41 } 42 return; 43 } 44 if(s.length()>=n+1&&check(0)) 45 { 46 int l=tmp; 47 s+='0'; 48 dfs(num+1); 49 s.erase(s.end()-1); 50 exist[l]=0; 51 } 52 if(s.length()<=length+1&&check(1)) 53 { 54 int l=tmp; 55 s+='1'; 56 dfs(num+1); 57 s.erase(s.end()-1); 58 exist[l]=0; 59 } 60 } 61 int main() 62 { 63 scanf("%d",&n);length=1<<n; 64 for(int i=1;i<=n;i++)s+='0';dfs(1); 65 }