太鼓达人【欧拉回路】【DFS】
题目大意:
给出一个01串,从不同的位置出发沿顺时针方向找可以得到个长度为的01串。且这个01串是互不相同的。给出K的值,请你求出的值,并给出字典序最小的方案。
3
00010111
思路:
,打标了解一下233
但是打到,跑了一个半小时都没跑出来。。。(时间复杂度:)
正解是欧拉回路。
但是我打的和其他大佬打的。。。
差距怎么这么大啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!
前面三页都是的。。。
我跑的十分的慢的原因是我先跑了一个的全拍列,再求出十进制的数字,最后求出答案。但是他们直接,遍跑遍建边就过了。。。
这道题求出01串的全排列后,将他们的十进制打出来,再跑一遍,找出欧拉回路,输出答案就可以了。
#include <cstdio>
#include <iostream>
#include <string>
using namespace std;
int n,m,a[3001][3001],num[3001][15],t[3001],mi[15],ans[3001],sum,o;
string head[3001],tail[3001];
bool ok,p[3001];
void dfs1(int x) //全排列
{
if (x>n) //找到一种全排列
{
for (int i=1;i<=n;i++)
{
num[m][i]=t[i];
if (i>1) tail[m]+=(char)t[i]+48;
if (i<n) head[m]+=(char)t[i]+48;
}
m++;
return;
}
for (int i=0;i<=1;i++)
{
t[x]=i;
dfs1(x+1);
t[x]=0;
}
return;
}
int conversion(int x) //转化为十进制
{
sum=0;
for (int i=1;i<=n;i++)
sum+=mi[i]*num[x][i];
return sum;
}
void dfs2(int x,int k) //求欧拉回路
{
if (k>m&&x==o) //找到欧拉回路
{
ok=true;
return;
}
for (int i=0;i<m;i++)
if (a[x][i]&&!p[i]) //可以通往这条边
{
p[i]=true;
dfs2(i,k+1);
if (ok) //找到欧拉回路
{
ans[k]=i&1; //二进制最后一位
return;
}
p[i]=false;
}
}
int main()
{
scanf("%d",&n);
dfs1(1); //求全排列
printf("%d ",m);
mi[n]=1;
for (int i=n-1;i>=1;i--)
mi[i]=mi[i+1]*2;
for (int i=0;i<m;i++)
for (int j=0;j<m;j++)
if (i!=j&&head[j]==tail[i])
{
a[conversion(i)][conversion(j)]=1; //转十进制
}
o=m-1;
dfs2(o,1);
for (int i=1;i<=m;i++) printf("%d",ans[i]);
return 0;
}