bzoj1330: Editing a Book

传送门
我们可直接暴力广搜算答案。
但是你会发现你预处理完就要20s+
于是我们考虑折半。
我们首先计算出答案小于3的部分
然后我们对于每次询问倒着广搜算出答案
然后你就可以卡过去啦

#include
#define ll long long
using namespace std;
mapint> mp,mp1;
int a[12],b[12],h,t,cnt;
ll x,y,q[500005];
ll cal(int *a){
    ll s=0;
    for (int i=a[0];i>=0;i--)
        s=s*10+a[i];
    return s;
}
void get(ll x,int *a){
    a[0]=x%10; x/=10;
    for (int i=1;i<=a[0];i++)
        a[i]=x%10,x/=10;
}
int main(){
    for (int i=1;i<=9;i++){
        for (int j=1;j<=i;j++) a[j]=j;
        a[0]=i;
        x=cal(a);
        q[++t]=x;
        mp[x]=1;
    }
    while (h!=t&&t!=409113){
        x=q[++h]; get(x,a);
        int dis=mp[x];
        if (dis>3) break;
        for (int l=1;l<=a[0];l++)
            for (int r=l;r<=a[0];r++)
                for (int k=1;k<=a[0]-r+l;k++){
                    b[0]=a[0]; cnt=0;
                    for (int i=1,j=(l==1?r+1:1);i<=a[0]-r+l;i++)
                        if (i==k)
                            for (int p=l;p<=r;p++)
                                b[++cnt]=a[p];
                        else b[++cnt]=a[j],j=j==l-1?r+1:j+1;
                    y=cal(b);
                    if (!mp[y]) q[++t]=y,mp[y]=dis+1;
                }
    }
    scanf("%d",&b[0]);
    while (b[0]){
        for (int i=1;i<=b[0];i++)
            scanf("%d",&b[i]);
        h=0; t=1;
        q[1]=cal(b);
        mp1.clear();
        mp1[cal(b)]=1;
        while (h!=t){
            x=q[++h]; get(x,a);
            if (mp[x]){
                printf("%d\n",mp[x]+mp1[x]-2);
                break;
            }
            for (int l=1;l<=a[0];l++)
                for (int r=l;r<=a[0];r++)
                    for (int k=1;k<=a[0]-r+l;k++){
                        b[0]=a[0]; cnt=0;
                        for (int i=1,j=(l==1?r+1:1);i<=a[0]-r+l;i++)
                            if (i==k)
                                for (int p=l;p<=r;p++)
                                    b[++cnt]=a[p];
                            else b[++cnt]=a[j],j=j==l-1?r+1:j+1;
                        y=cal(b);
                        if (!mp1[y]) q[++t]=y,mp1[y]=mp1[x]+1;
                    }
        }
        scanf("%d",&b[0]);
    }
}

你可能感兴趣的:(辣鸡八中,爆搜)