暴力待填坑 IDA* UVA11212 编辑文本

UVA 11212编辑文本

我觉得我自己写写不出来_(:з」∠)_

核心部分

bool dfs(int d,int maxd){
    if(d*3 + h() >= maxd*3)return false;//启发式函数估计
    if(ans_sort())return true;//判断是否顺序正确
    int o[maxn],b[maxn];
    memcpy(o,a,sizeof(a));
    for(int i = 0;i < n; i++)
        {//设置剪切文本的最左边下标
        for(int j = i;j < n; j++)
        {//设置剪切文本的最右边下标
            int cnt = 0;
            for(int k = 0;k < n;j++)
                if(k < i || k > j)b[cnt++] = a[k];//将有顺序的接在一起
            for(int k = 0;k <= cnt; k++)
            {
                int cnt2 = 0;
                for(int p = 0;p < k; p++)a[cnt2++] = b[p];//插入文本之前的文本
                for(int p = i;p <= j;p++)a[cnt2++] = o[p];//插入的文本
                for(int p = k;p < cnt;p++)a[cnt2++] = b[p];//插入文本之后的文本

                if(dfs(d+1,maxd))return true;//深搜
                memcpy(a,o,sizeof(a));//还原a数组方便下次递归
            }

        }
    }
    return false;
}


 

    //690ms
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int n;
    const int N=15;
    int book[N];

    bool ok()
    {

        for(int i=0;i<n;++i)
            if(book[i]!=i+1)
            return false;
        return true;

    }
    int h()//还有多少个不在状态的
    {
        int cnt=0;
        for(int i=0;i<n-1;++i)
        {
            if(book[i]+1!=book[i+1]) ++cnt;
        }
        if(book[n-1]!=n) ++cnt;//比如出现9 1 2 3 4 5 6 7 8的情况 相当于是首尾的判断,因为我先前只判断了n-1位的状态   非常容易忘记
        return cnt;

    }
    bool dfs(int d,int maxd)
    {
        //在每个状态下去深搜,每次都是个完全状态,所以每层都要判断
        if(h()>3*(maxd-d)) return false;
        if(ok()) return true;

        //开始搜每个状态
        int old[N];
        int x[N];

        for(int i=0;i<n;++i)
            for(int j=i;j<n;++j)
        {   memcpy(old,book,sizeof(book));
               //ctrl+x   //每个开头每个结尾下都应该有个新的去存
            int cnt=0;

            for(int k=0;k<n;++k)
                if(k<i||k>j)
                    x[cnt++]=book[k];
            //for(int i=0;i<cnt;++i)
            //至此已经把剩下的拼在了一起  开始枚举插入位置 有cnt个字母,枚举在第k位置的前面插入
            for(int k=0;k<=cnt;++k)  //=cnt 就是在最后一个后插入,有cnt个字母,有cnt+1个插入的位置
            {

                int cnt2=0;
                for(int p=0;p<k;++p) book[cnt2++]=x[p];
                for(int p=i;p<=j;++p) book[cnt2++]=old[p];
                for(int p=k;p<cnt;++p) book[cnt2++]=x[p];   //敲成k++了  经常这样错,一旦死循环一般都是这样,把循环变量给改了

                if(dfs(d+1,maxd)) return true;
                memcpy(book,old,sizeof(old));
            }
        }
        return false;
    }
    int solve()
    {
        if(ok()) return 0;
        for(int maxd=0;maxd<=8;++maxd)
        {
           if(dfs(0,maxd)) return maxd;
        }
        return -1;
    }
    int main()
    {
        int kase=0;
        while(scanf("%d",&n)!=EOF&&n)
        {
            ++kase;
            memset(book,0,sizeof(book));
            for(int i=0;i<n;++i)
                scanf("%d",&book[i]);
            printf("Case %d: %d\n",kase,solve());
        }

    }

猜你喜欢

转载自blog.csdn.net/iroy33/article/details/88628308
今日推荐