Editing a Book 搜索 + meet in the middle

我们可以发现最多只会进行5次操作。
由此我们从双向跑dfs,用一个unordered_map来保存状态,枚举一下两边的深度即可。
如果4次仍然不可行,则只有可能是5次。所以正反最多只需要搜2层
code:

#include<cstdio>
#include<tr1/unordered_map>
#include<algorithm>
#include<queue>
using namespace std;
using namespace std :: tr1;
unordered_map<long long ,int>F[3];
queue<long long>Q; 
int n, A[20], w[20];
int getnext(int arr[],int cur)
{
    while(cur < n && arr[cur+1] == arr[cur] + 1)++cur;
    return cur;
}
long long get(int arr[])
{
    long long  tmp = 0;
    for(int i = 1;i <= n; ++i)
    {
        tmp = tmp * 10 + arr[i];
    }
    return tmp;
}
int dfs(int cur,int target,int arr[],int ty)
{
    if(cur == target)
    {              
        long long fin = get(arr);
        F[ty][fin] = -1;                      
        Q.push(fin);   
        if(F[ty^1][fin] == -1) return 1;                   
        return 0;
    }
    int h[12];
    for(int lefts = 1;lefts <= n; ++lefts)                                
    {
        for(int rights = lefts; rights <= n; ++rights)       
        {
            int pos = 0;
            for(int fronts = 1; fronts < lefts; ++fronts)                 
            {
                pos = 0;
                for(int i = 1; i < fronts; ++i) h[++pos] = arr[i];                   
                for(int i = lefts; i <= rights ;++i) h[++pos] = arr[i];             
                for(int i = fronts;i < lefts; ++i) h[++pos] = arr[i];
                for(int i = rights + 1; i <= n; ++i)h[++pos] = arr[i];
                if(dfs(cur + 1,target,h,ty)) return 1;
            }
            for(int backs = rights + 1; backs <= n; ++backs)
            {
                pos = 0;
                for(int i = 1;i < lefts; ++i) h[++pos] = arr[i];
                for(int i = rights + 1;i <= backs; ++i)h[++pos] = arr[i];
                for(int i = lefts; i <= rights ;++i)h[++pos] = arr[i];
                for(int i = backs + 1;i <= n; ++i)h[++pos] = arr[i];
                if(dfs(cur + 1, target,h,ty))return 1;
            }
        }
    }
    return 0;
}
int main()
{
    int cas = 0;
    while(1)
    {
        scanf("%d",&n);
        if(!n)break;
        for(int i = 1;i <= n;++i)
        {
            scanf("%d",&A[i]);
            w[i] = A[i];
        }
        sort(w + 1, w + 1 + n);
        if(getnext(A,1) == n)
        {
            printf("0
");
            continue;
        }
        while(!Q.empty())
        {
            F[0][Q.front()] = 0, F[1][Q.front()] = 0;
            Q.pop();
        }
        F[1][get(w)] = -1;
        if(dfs(0,1,A,0))printf("1
");
        else if(dfs(0,1,A,0) || dfs(0,1,w,1))printf("2
");
        else if(dfs(0,2,A,0) || dfs(0,1,w,1))printf("3
");
        else if(dfs(0,2,A,0) || dfs(0,2,w,1))printf("4
");
        else printf("5
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/guangheli/p/9845201.html