uva 11212 - Editing a Book

来源:互联网 发布:淘宝级别的等级划分 编辑:程序博客网 时间:2024/05/22 02:12

原题地址

解题思路:迭代加深搜索。(完全没有使用紫书上面提到的三种策略,直接穷举了剪切和粘贴的位置,不过就如LRJ所说,虽然不怎么快,但是思路很好懂,详见注释)

#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn=9;int n,a[maxn];//h()代表的是后继不正确的数字,一次最多改变三个数字的后继数字int h(){    int cnt=0;    for(int i=0;i<n-1;i++){        if(a[i]+1!=a[i+1]) cnt++;    }    if(a[n-1]!=n) cnt++;    return cnt;}bool is_sorted(){    for(int i=0;i<n;i++){        if(a[i]!=i+1) return false;    }    return true;}bool dfs(int d,int maxd){    //剪枝条件    if(3*d+h()>3*maxd) return false;    if(is_sorted()) return true;    int b[maxn],olda[maxn];    memcpy(olda,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;k++){                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++]=olda[p];                }                for(int p=k;p<cnt;p++){                    a[cnt2++]=b[p];                }                if(dfs(d+1,maxd)) return true;                memcpy(a,olda,sizeof(olda));            }        }    }    return false;}int solve(){    if(is_sorted()) return 0;    //代码仓库里里提到实验后最大编辑次数为5.    int ans=5;    for(int maxd=1;maxd<ans;maxd++){        if(dfs(0,maxd)){            return maxd;        }    }    return ans;}int main(){    //freopen("in.txt","r",stdin);    int kase=0;    while(scanf("%d",&n)==1&&n){        for(int i=0;i<n;i++){            scanf("%d",&a[i]);        }        printf("Case %d: %d\n",++kase,solve());    }    return 0;}
0 0
原创粉丝点击