Luogu P2324 [SCOI2005]骑士精神

Luogu P2324 [SCOI2005]骑士精神


题意

(我也会简化题意了qwq)

给一个矩阵,有一个空格在其中,每次操作可以按规则将其他格子与这个空格交换,多少次达到目标状态?
规则:马在棋盘上跳的规则(当然不存在被堵了马脚的情况quq)

爆搜吗,把空格当马跳,肯定会炸掉的。。。
标签是启发式搜索还有一个神秘的A*算法
sto向骑(xie)士(e)精(ti)神(mu)低头。。。我又膜(bu)了(si)题(kao)解(le)
lhy向我推荐的这篇题解还挺好的

importance:

要把当前相差的方格数记录,努力使相差的方格数减少,还要防止它走回去
#include<cstdio>
#include<cstring>

//01int map[10][10],ans,k,tot,sx,sy;
char s1[1010];
int goal[6][6]={0,0,0,0,0,0,
                0,1,1,1,1,1,
                0,0,1,1,1,1,
                0,0,0,2,1,1,
                0,0,0,0,0,1,
                0,0,0,0,0,0};
int dx[8]={1,1,2,2,-2,-2,-1,-1};
int dy[8]={-2,2,-1,1,-1,1,-2,2};


int dfs(int x,int y,int t,int sum,int back)
{
    if(t>15)return 0;
    //if(sum>0)
    //printf("%d %d %d %d %d\n",x,y,t,sum,back);
    if(sum==0&&t<=15)
    {
        if(t<ans)ans=t;
        return 0;
    }
    for(int i=0;i<8;i++)
    {
        if(i+back!=7)
        {
            int xx=x+dx[i];
            int yy=y+dy[i];
            int fff1=0,fff2=0;
            if(xx>=1&&yy>=1&&xx<=5&&yy<=5)
            {
                int num=sum;fff1=0;fff2=0;
                if(map[x][y]!=goal[x][y])fff1=1;
                if(map[xx][yy]!=goal[xx][yy])fff2=1;
                int b=map[xx][yy];map[xx][yy]=map[x][y];map[x][y]=b;
                if(map[xx][yy]==goal[xx][yy])
                {
                    if(fff2)
                        num--;
                }   
                else
                {
                    if(fff2==0)
                        num++;
                }
                if(map[x][y]==goal[x][y])
                {
                    if(fff1)
                        num--;
                }   
                else
                {
                    if(fff1==0)
                        num++;
                }
                if(t+1+num<=17)
                    dfs(xx,yy,t+1,num,i); 
                b=map[xx][yy];map[xx][yy]=map[x][y];map[x][y]=b;
            } 
        }
    }
}

int main()
{
    scanf("%d",&k);

    while(k--)
    {
        ans=999999999,tot=0;
        for(int i=1;i<=5;i++)
        {
            scanf("%s",s1+1);
            for(int j=1;j<=5;j++)
            {
                if(s1[j]=='1')
                {
                    map[i][j]=1;
                }
                if(s1[j]=='0')
                {
                    map[i][j]=0;
                } 
                if(s1[j]=='*')
                {
                    sx=i;sy=j;
                    map[i][j]=2;
                }
                if(map[i][j]!=goal[i][j])tot++;

            }
        }//printf("%d\n",tot);

        /*for(int i=1;i<=5;i++)
        {
            for(int j=1;j<=5;j++)
            {
                printf("%d",map[i][j]);
            }printf("\n");
        }*/
        dfs(sx,sy,0,tot,-1);
        //x坐标,y坐标,步数,相差数,防止返回的玩意儿 
        if(ans==999999999)
        {
            printf("-1\n");continue;
        }
        printf("%d\n",ans);
    }
}

因为一直没看到ans==999999999那里少打了一个=
所以一直不明白为什么只输出-1还多浪费了一个中午QAQ

猜你喜欢

转载自blog.csdn.net/qq_42142540/article/details/80418955
今日推荐