• BZOJ 1085 骑士精神


    Time Limit: 10 Sec Memory Limit: 162 MB
    Submit: 3229 Solved: 1908
    [Submit][Status][Discuss]
    Description

      在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。

    这里写图片描述

    Input

      第一行有一个正整数T(T<=10),表示一共有N组数据。接下来有T个5×5的矩阵,0表示白色骑士,1表示黑色骑
    士,*表示空位。两组数据之间没有空行。

    Output

      对于每组数据都输出一行。如果能在15步以内(包括15步)到达目标状态,则输出步数,否则输出-1。

    Sample Input

    2

    10110

    01*11

    10111

    01001

    00000

    01011

    110*1

    01110

    01010

    00100

    Sample Output

    7

    -1

    题解

    看数据范围不大,A*搜索,估价函数为剩余没有到达的骑士的个数。
    

    代码

    #include<bits/stdc++.h>
    
    using namespace std;
    //const int MAXN = 
    
    int ans=16;
    int T,n,a[10][10];
    int xx[8]={-2,-1,1,2,2,1,-1,-2},
        yy[8]={1,2,2,1,-1,-2,-2,-1};
    int win[5][5]={1,1,1,1,1,
                   0,1,1,1,1,
                   0,0,2,1,1,
                   0,0,0,0,1,
                   0,0,0,0,0};
    
    inline int jud(){
        int sum=0;
        for(register int i=1;i<=5;i++)
            for(register int j=1;j<=5;j++){
                if(a[i][j]!=win[i-1][j-1]) sum++;
            }
        return sum;
    }
    
    inline void dfs(int x,int y,int prex,int prey,int cnt){
        if(x==prex && y==prey) return;
        if(cnt>15) return; 
        int kk=jud();
        if(kk==0) {ans=min(ans,cnt);return;}
        if(kk+cnt>ans) return;
        for(int k=0;k<=7;k++){
            int i=x+xx[k];
            int j=y+yy[k];
            if(i>=1 && i<=5 && j>=1 && j<=5){
                a[x][y]^=a[i][j]^=a[x][y]^=a[i][j];
                dfs(i,j,x,y,cnt+1);
                a[x][y]^=a[i][j]^=a[x][y]^=a[i][j];
            }
        }
    }
    
    int main(){
        ios::sync_with_stdio(false);
        cin>>T;
        while(T--){
            char ch;
            int sti,stj;
            ans=16;
            for(register int i=1;i<=5;i++){
                for(register int j=1;j<=5;j++){ 
                    cin>>ch;
                    if(ch=='0') a[i][j]=0;
                    else if(ch=='1') a[i][j]=1;
                    else a[i][j]=2,sti=i,stj=j;
    //              cout<<a[i][j];
                }
    //          cout<<"
    ";
            }
            dfs(sti,stj,0,0,0);
            if(ans>15) cout<<-1<<endl;
            else cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    NOIP2017 D1T2 时间复杂度
    NOIP2017 游记
    NOIP2017 Day-1 模板荟萃
    NOIP2013 货车运输 倍增
    洛谷3933 Chtholly Nota Seniorious 二分答案+贪心
    洛谷2474 [SCOI2008] 天平 差分约束->枚举
    bzoj1270 BeijingWc2008 雷涛的小猫 DP
    poj1061--青蛙的约会--扩展欧几里得
    “整除”的相关
    poj1067--取石子游戏--(神奇的黄金分割比)
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9677038.html
Copyright © 2020-2023  润新知