zoukankan      html  css  js  c++  java
  • 【洛谷】2324:[SCOI2005]骑士精神【IDA*】

    P2324 [SCOI2005]骑士精神

    题目描述

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1: 复制
    2
    10110
    01*11
    10111
    01001
    00000
    01011
    110*1
    01110
    01010
    00100
    
    输出样例#1: 复制
    7
    -1
    

    说明


    喜欢了!不枉我研究那么久搜索QAQ

    不过还是卡了一会儿,因为在估价时不能算空格,空格是跟随别人走的。

    然后就是迭代加深和A*的套路了...枚举最大深度,估价剪枝,然后直接暴力跳就行叻!

    #include<bits/stdc++.h>
    using namespace std;
    
    int maxdep;
    
    int zl[9][2] = {{2, 1}, {-2, 1}, {1, 2}, {-1, 2}, {1, -2}, {-1, -2}, {2, -1}, {-2, -1}};
    
    int st[6][6], now[6][6], G[6][6];
    char s[6][10];
    
    void init() {
        for(int i = 1; i <= 5; i ++)
            for(int j = 1; j <= 5; j ++) {
                if(i <= 2 && j >= i)        st[i][j] = 1;
                else if(i <= 3 && j < 3)    st[i][j] = 0;
                else if(i == 3 && j == 3)    st[i][j] = 2;
                else if(i >= 4 && j <= i)    st[i][j] = 0;
                else st[i][j] = 1;
            }
    }
    
    bool check() {
        for(int i = 1; i <= 5; i ++)
            for(int j = 1; j <= 5; j ++) {
                if(now[i][j] != st[i][j])    return 0;
            }
        return 1;
    }
    
    int cot(int x, int y) {
        int num = 0;
        for(int i = 1; i <= 5; i ++)
            for(int j = 1; j <= 5; j ++)
                if(st[i][j] != now[i][j] && st[i][j] != 2)    num ++;
        return num;
    }
    
    bool pd(int x, int y) {
        if(x >= 1 && x <= 5 && y >= 1 && y <= 5)    return 1;
        return 0;
    }
    
    int fl, flag;
    void dfs(int dep, int x, int y) {
        if(fl)    return ;
        if(dep == maxdep) {
            if(check()) fl = 1;
            return ;
        }
        if(dep + cot(x, y) > maxdep)    return ;
        for(int i = 0; i < 8; i ++) {
            int xx = x + zl[i][0], yy = y + zl[i][1];
            if(pd(xx, yy)) {
                swap(now[x][y], now[xx][yy]);
                dfs(dep + 1, xx, yy);
                if(fl)    return ;
                swap(now[x][y], now[xx][yy]);
            }
        }
        if(fl)    return ;
    }
    
    int main() {
        int T;
        scanf("%d
    ", &T);
        init();
        while(T --) {
            int x, y;
            flag = 0;
            for(int i = 1; i <= 5; i ++) {
                scanf("%s", s[i] + 1);
            }
            for(int i = 1; i <= 5; i ++) {
                for(int j = 1; j <= 5; j ++) {
                    if(s[i][j] == '1')    G[i][j] = 1;
                    else if(s[i][j] == '0')    G[i][j] = 0;
                    else G[i][j] = 2, x = i, y = j;
                }
            }
            for(maxdep = 0; maxdep <= 15; maxdep ++) {
                fl = 0;
                for(int i = 1; i <= 5; i ++)
                    for(int j = 1; j <= 5; j ++)
                        now[i][j] = G[i][j];
                dfs(0, x, y);
                if(fl) {
                    printf("%d
    ", maxdep);    flag = 1;    break;
                }
            }
            if(!flag)    printf("-1
    ");
        }
        return 0;
    }
  • 相关阅读:
    Perl分片技术
    Perl的time、localtime和gmtime函数
    Perl文件名通配和文件查找
    Perl复制、移动、重命名文件/目录
    Perl文件、目录常用操作
    Perl文件测试操作和stat函数
    Linux终端会话实时共享(kibitz)
    Perl的IO操作(2):更多文件句柄模式
    Perl的IO操作(1):文件句柄
    Perl文件句柄相关常量变量
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/9768968.html
Copyright © 2011-2022 走看看