• SP4546 ANARC08A


    题意:
    旋转A,B,C,D,一并带着相邻的四个数字旋转。
    给定初始状态,求在给定次数下,能否到达如figure(a)的状态。
    输入:十位字符串,第一位为给定次数,后九位为初始状态。

    提交次数:3次(然鹅洛谷上的remotejudge一直CE)
    错误:mxd初值设成了1,qwq
     
    题解:
    思路:搜索,IDA*
    估价函数$h()$:每个数到应到位置的曼哈顿距离$frac {sum dis[i]}{4}$
    正确性:每次旋转至多将这个值减少$4$
     
    代码:
    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<cstring>
    #define R register int
    using namespace std;
    #define ull unsigned long long
    #define ll long long
    #define pause (for(R i=1;i<=10000000000;++i))
    const int N=10;
    const int p[4]={1,2,4,5};
    char s[N];
    const int d[N][2]={
    {0,0},
    {1,1},
    {1,2},
    {1,3},
    {2,1},
    {2,2},
    {2,3},
    {3,1},
    {3,2},
    {3,3}
    };
    int mp[N],mxd;
    inline void rot(int* a,int d) {
        memmove(a+d+1,a+1,sizeof(int)*4);
        if(d==1) a[1]=a[5],a[5]=0;
        if(d==-1) a[4]=a[0],a[0]=0;
    }
    inline void change(int pos,int d) {
        R a[6];
        a[1]=mp[pos],a[2]=mp[pos+1],a[3]=mp[pos+4],a[4]=mp[pos+3];
        rot(a,d);
        mp[pos]=a[1],mp[pos+1]=a[2],mp[pos+4]=a[3],mp[pos+3]=a[4];
    }
    inline int h() { R ret=0;
        for(R i=1;i<=9;++i) {
            ret+=abs(((i-1)/3+1)-d[mp[i]][0])+abs((i-1)%3+1-d[mp[i]][1]);
        } return (ret+3)/4;
    }
    inline bool dfs(int s,int lstp,int lstd) {
        if(h()+s>mxd) return false;
        if(!h()) return true;
        R tmp[10];
        memcpy(tmp,mp,sizeof(mp));
        for(R i=0;i<=3;++i) for(R j=-1;j<=1;j+=2) if(!(i==lstp&&j==-lstd)) {
            change(p[i],j);
            if(dfs(s+1,i,j)) return true;
            memcpy(mp,tmp,sizeof(mp));
        } return false;
    }
    signed main() { R T=0,Lim; 
        while(1) { register bool flg=true;
            scanf("%s",s); Lim=s[0]^48;
            for(R i=1;i<=9;++i) mp[i]=s[i]^48,flg&=(s[i]==48);
            if(flg) break;
            for(mxd=0;mxd<=Lim&&!dfs(0,-1,0);++mxd) ;    
            printf("%d. %d
    ",++T,mxd<=Lim?mxd:-1);
        } 
    }

    2019.07.13

     
     
  • 相关阅读:
    perl的文件操作(2)
    使用委派调用对象的方法
    C#GDI+ TextureBrush画刷
    C#GDI+的PathGradientBrush类的使用
    C#异常对象和多catch块
    tr使用
    vim sed删除前N个字符 删除空行等 [转]
    C#检索线程状态
    C#理解线程
    C语言字符串函数大全
  • 原文地址:https://www.cnblogs.com/Jackpei/p/11182750.html
Copyright © 2020-2023  润新知