1 条题解

  • 2
    @ 2021-8-7 21:07:52

    C++ :

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 15;
    
    int n;
    int q[N], w[5][N];
    
    int F()//求当前估价函数
    {
        int res = 0;
        for (int i = 0; i + 1 < n; i ++ )
            if (q[i + 1] != q[i] + 1)
                res ++ ;        //求当前错误后继的个数
        return (res + 2) / 3;//求上限
    }
    
    bool check()//判断所有书的后继是否准确
    {
        for (int i = 0; i < n; i ++ )
            if (q[i] != i + 1)
                return false;
        return true;
    }
    
    bool dfs(int depth, int maxd)
    {
        if (depth + F() > maxd) return false;//若当前值+估计值大于最大层数,回溯
        if (check()) return true;//判断所有书是否符合顺序
    
        for (int l = 0; l < n; l ++ )//枚举移动数字断的左端
            for (int r = l; r < n; r ++ )// 枚举移动数字断的右端
                for (int k = r + 1; k < n; k ++ ) //枚举移动目标点     由于移前移后都是一样的,所以只考虑向移后
                {
                    memcpy(w[depth], q, sizeof q);//保存当前序列
    
                    int x, y;
                    for (x = r + 1, y = l; x <= k; x ++, y ++ ) q[y] = w[depth][x];//先移动R后K前的数字断
                    for (x = l; x <= r; x ++, y ++ ) q[y] = w[depth][x];//再移动LR数字断到K后
    
                    if (dfs(depth + 1, maxd)) return true;//继续向下搜索
                    memcpy(q, w[depth], sizeof q);//恢复现场
                }
        return false;
    }
    
    int main()
    {
        int M;
        cin>>M;
        while (M -- )
        {
            cin>>n;
            for (int i=0;i<n;i++)
                cin>>q[i];//输入排书序列
    
            int depth = 0;
            while (depth < 5 && !dfs(0, depth)) depth ++ ;//开始迭代加深的深度优先搜索
            if (depth > 4) cout<<"5 or more"<<endl;
            else cout<<depth<<endl;
        }
    
        return 0;
    }
    
    • 1

    信息

    ID
    91
    时间
    1000ms
    内存
    128MiB
    难度
    1
    标签
    递交数
    38
    已通过
    35
    上传者