• 【Luogu】P2324骑士精神(IDA*)


      题目链接

      当guess>limit-deep的时候return就好了。

      guess是估价函数,值为不在自己地盘上的骑士个数。limit是本次迭代阈值。deep是已经走了多少步。

      这个优化是显然的。因为一次跳跃最多可以复原一个骑士。假设最好的情况,所有的骑士都能一步跳回去,如果这样还不能在阈值步数内复原,那不论如何都没法复原了——也就没有继续搜下去的必要了。

      放上代码

      

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cctype>
    #include<map>
    using namespace std;
    map<long long,bool>vis;
    inline long long read(){
        long long num=0,f=1;
        char ch=getchar();
        while(!isdigit(ch)){
            if(ch=='-')    f=-1;
            ch=getchar();
        }
        while(isdigit(ch)){
            num=num*10+ch-'0';
            ch=getchar();
        }
        return num*f;
    }
    
    long long goal;
    
    int u[9]={0,-2,-1,1,2,2,1,-1,-2};
    int w[9]={0,-1,-2,-2,-1,1,2,2,1};
    
    int s[6][6]={   {0, 0, 0, 0, 0, 0},
                    {0, 1, 1, 1, 1, 1},
                    {0,-1, 1, 1, 1, 1},
                    {0,-1,-1, 0, 1, 1},
                    {0,-1,-1,-1,-1, 1},
                    {0,-1,-1,-1,-1,-1}    };
    
    int q[6][6];
    char c[10];
    int ans;
    
    void dfs(int deep,int limit,int guess,int x,int y){
        if(guess>limit-deep)    return;
        if(guess==0){
            ans=ans>deep?deep:ans;
            return;
        }
        for(register int e=1;e<=8;++e){
            int a=x+u[e],b=y+w[e];
            if(a>0&&b>0&&a<6&&b<6){
                int New=guess;
                /*if(q[x][y]==s[x][y]&&q[x][y]!=s[a][b])    --New;
                if(q[x][y]!=s[x][y]&&q[x][y]==s[a][b])    ++New;*/
                if(q[a][b]==s[a][b]&&q[a][b]!=s[x][y])    ++New;
                if(q[a][b]!=s[a][b]&&q[a][b]==s[x][y])    --New;
                q[x][y]=q[a][b];    q[a][b]=0;
                if(New<=limit-deep-1)    dfs(deep+1,limit,New,a,b);
                q[a][b]=q[x][y];    q[x][y]=0;
            }
        }
    }
    
    int main(){
        int T=read();
        while(T--){
            ans=0x7fffffff;
            //vis.clear();
            int x,y,start=0;
            long long val;
            for(int i=1;i<=5;++i){
                scanf("%s",c+1);
                for(int j=1;j<=5;++j){
                    if(c[j]=='*'){
                        x=i;y=j;
                        q[i][j]=0;
                    }
                    else q[i][j]=(c[j]-'0'==1?1:-1);
                    if(q[i][j]!=0&&q[i][j]!=s[i][j])    start++;
                }
            }
            /*for(int i=1;i<=5;++i,printf("
    "))
                for(int j=1;j<=5;++j)    printf("%d ",q[i][j]);*/
            if(start==0){
                printf("0
    ");
                continue;
            }
            for(int i=0;i<=15;++i){
                //vis.clear();
                dfs(0,i,start,x,y);
                if(ans!=0x7fffffff){
                    printf("%d
    ",ans);
                    break;
                }
            }
            if(ans!=0x7fffffff)    continue;
            printf("-1
    ");
        }
    }
  • 相关阅读:
    webIDE 第二篇博文
    前端第一天
    记昨天
    入职第四天
    入职第二天
    linux常用命令,自己总结
    一切从头开始
    在服务器上搭建SVN
    Dynamic CRM 365学习历程--JS
    Dynamic CRM 365学习历程--有关CRM的学习过程种需要注意的事项
  • 原文地址:https://www.cnblogs.com/cellular-automaton/p/7679843.html
Copyright © 2020-2023  润新知