zoukankan      html  css  js  c++  java
  • BZOJ1085: [SCOI2005]骑士精神

    【传送门:BZOJ1085


    简要题意:

      有一个5*5的棋盘,棋盘上有12个白棋子,12个黑棋子,和一个空格,每只棋子只能按照马走日的规则移动,求出最少步数达到以下状态


    题解:

      DFS+A*

      DFS很容易做,不过时间复杂度太高

      所以用A*来优化时间

      A*的好处预判当前递归到结束得到的值,从而判断是否进入递归,部分判断,避免遍历太多无用点


    参考代码:

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int a[6][6];
    const int dx[9]={0,1,1,-1,-1,2,2,-2,-2};
    const int dy[9]={0,2,-2,2,-2,1,-1,1,-1};
    bool bk;
    int ans[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}
    };
    bool pd()
    {
        for(int i=1;i<=5;i++) for(int j=1;j<=5;j++) if(a[i][j]!=ans[i][j]) return false;
        return true;
    }
    int w;
    bool pdA(int k)
    {
        int s=0;
        for(int i=1;i<=5;i++)
        {
            for(int j=1;j<=5;j++)
            {
                if(a[i][j]!=ans[i][j])
                {
                    s++;
                    if(s+k>w) return false;
                }
            }
        }
        return true;
    }
    void dfs(int x,int y,int k)
    {
        if(bk==true) return ;
        if(k==w)
        {
            if(pd()==true) bk=true;
            return ;
        }
        else
        {
            for(int i=1;i<=8;i++)
            {
                int tx=x+dx[i],ty=y+dy[i];
                if(tx<1||tx>5||ty<1||ty>5) continue;
                swap(a[x][y],a[tx][ty]);
                if(pdA(k)==true) dfs(tx,ty,k+1);
                swap(a[x][y],a[tx][ty]);
            }
        }
    }
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            char st[10];
            int kx,ky;
            for(int i=1;i<=5;i++)
            {
                scanf("%s",st+1);
                for(int j=1;j<=5;j++)
                {
                    if(st[j]=='*')
                    {
                        a[i][j]=2;
                        kx=i,ky=j;
                    }
                    else a[i][j]=st[j]-'0';
                }
            }
            bk=false;
            for(w=1;w<=15;w++)
            {
                dfs(kx,ky,0);
                if(bk==true)
                {
                    printf("%d
    ",w);
                    break;
                }
            }
            if(bk==false) printf("-1
    ");
        }
        return 0;
    }

     

  • 相关阅读:
    将参数传递给线程(Vc#2005)
    ADO.NET更新ACCESS碰到的怪异问题
    MVCRESTSilverLight 之 MapServiceRoute
    MEF Export 和 Import 委托
    MVCRESTSilverLight 之MainPage.xaml.cs
    设计模式访问者
    MVCRESTSilverLight 之 ViewModels\MainViewModel.cs
    MVCRESTSilverLight 之Api\CustomerApi.cs
    MVCRESTSilverLight 之 RestExample.Model.Silverlight\Customer.cs
    MVCRESTSilverLight 之 HttpConfiguration
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8608399.html
Copyright © 2011-2022 走看看