• 太鼓达人【欧拉回路】【DFS】


    题目大意:

    给出一个01串,从不同的位置出发沿顺时针方向找可以得到M个长度为K的01串。且这M个01串是互不相同的。给出K的值,请你求出M的值,并给出字典序最小的方案。
    Input

    3

    Output

    00010111

    思路:

    n11,打标了解一下233
    但是打到n=6,跑了一个半小时都没跑出来。。。(时间复杂度:O4n
    正解是欧拉回路。
    但是我打的和其他大佬打的。。。
    这里写图片描述
    差距怎么这么大啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊!!!
    前面三页都是1ms的。。。


    我跑的十分的慢的原因是我先跑了一个O(2n)的全拍列,再O(m2n)求出十进制的数字,最后O(2n)求出答案。但是他们直接O(2n),遍跑遍建边就过了。。。
    这道题求出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;
    }
  • 相关阅读:
    算法学习(二)——树状数组求逆序数
    ZOJ 2412 Farm Irrigation
    排列的生成算法(一)
    汉诺塔递归实现
    汇编(五)
    汇编(四)
    汇编(三)
    汇编(二)
    0103MySQL中的B-tree索引 USINGWHERE和USING INDEX同时出现
    0103如何通过索引长度确定是否使用全索引
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313029.html
Copyright © 2020-2023  润新知