• [SCOI2005]骑士精神


    (mathcal{color{red}{Description}})

    嗯,(15)步之内走不到就输出(-1).

    (mathcal{color{red}{Solution1}})

    这个题是我第一次写迭代加深ORZ…没想到并不简单啊。

    首先我们考虑如果移动每个不在原位子上的棋子,好像根本不可做,状态之间的关系错综复杂,所以我么考虑移动空格。

    那么,我们如何来定义每一步的状态呢?我们对于搜索的每一步,记录状态(sum)为“还剩下多少未归位的棋子”,然后迭代加深的层数便是最开始有多少未归位的棋子数~16。这个(16)显然是由步数上限(15)得来的,(+1)的原因是因为我的(code)是在第(n)层搜索之前判断是否到达规定的搜索深度(k)

    嗯,接着就要分下面几种情况来讨论:

    对于下一层状态(sum)而言(),设现在空格的位置为(A(x, y)),跳一步之后到达的位置是(A'(kx, ky)),那么这次操作就等价于(A)(A‘)位置的互换。

    1、如果换位之前,(A’)和正确的矩阵中(A')的颜色一致,但是(A)的颜色和正确矩阵中的(A’)位置颜色也相同,那换了和没换没有区别,所以并不考虑这一点。

    2、如果换位之前,(A’)和正确的矩阵中(A')的颜色一致,但是(A)的颜色和正确矩阵中的(A’)位置颜色不相同,那换了之后未归位数就会变多,所以(sum ++)

    if (now[kx][ky] == rht[kx][ky] && now[kx][ky] != rht[x][y]) sum ++ ;
    

    3、如果换位之前,(A’)和正确的矩阵中(A')的颜色不一致,但是(A)的颜色和正确矩阵中的(A’)位置颜色相同,那换了之后未归位数就会变少,所以(sum --)

    if (now[kx][ky] != rht[kx][ky] && now[kx][ky] == rht[x][y]) sum -- ;
    

    4、如果下一步走到了空格上,那么说明有空格归位了,$sum -- $

            if (rht[kx][ky] == -1) sum -- ;
    

    5、如果这一步走到了空格,那么下一步就势必要多一个未归位的,所以(sum ++)

            if (rht[x][y] == -1) sum ++ ;
    

    嗯,唐子川大佬给我讲的qwq。

    那么看起来好像比(5 imes 5)的枚举快多了,但我并不知道到何时我才会有这种素养让我能想出这种剪枝(QAQ).

    // luogu-judger-enable-o2
    //Flower学习专用 
    #include<cstdio>
    #include<iostream>
    #define rep(i, a, b) for(int i = a; i <= b; i ++)
    
    using namespace std ;
    bool mark = 0;
    char k ;
    int mp = 0, max_deep, T, stx, sty, i, kk;
    int fx[8]={-2,-2,-1,1,-1,1,2,2},
        fy[8]={-1,1,2, 2,-2,-2,-1,1};
    int now[6][6], rht[6][6] = { {},
                                {0, 1, 1, 1, 1, 1},
                                {0, 0, 1, 1, 1, 1},
                                {0, 0, 0, -1, 1, 1},
                                {0, 0, 0, 0, 0, 1},
                                {0, 0, 0, 0, 0, 0},
                               };
    bool knight(int step, int left, int last, int x, int y){
        if (step + left > max_deep) return 0;
        if (!left) return 1 ;
        int kx, ky;
        int j ;
        rep (j, 0, 7){
            if (j == 7 - last) continue ;
            kx = x + fx[j] ;
            ky = y + fy[j] ;
            int lleft = left ;
            if(kx < 1 || ky < 1 || kx > 5 || ky > 5) continue ;
            if (now[kx][ky] == rht[kx][ky] && now[kx][ky] != rht[x][y]) lleft ++ ;
            if (now[kx][ky] != rht[kx][ky] && now[kx][ky] == rht[x][y]) lleft -- ;
            if (rht[kx][ky] == -1)  lleft -- ;
            if (rht[x][y] == -1) lleft ++ ;
            swap(now[kx][ky], now[x][y]) ;
            if (knight(step + 1, lleft, j, kx, ky))  return 1 ;
            swap(now[kx][ky], now[x][y]) ;
        }
        return 0 ;
    }
    int main(){
        cin >> T ;
        while(T --){
            mp = 0 ;
            mark = 0 ;
            rep(i, 1, 5)
                rep(kk, 1, 5){
                    cin >> k ;
                    if (k == '*') {
                        now[i][kk] = -1 ;
                        stx = i ;
                        sty = kk ;	
                    }
                    else now[i][kk] = k - 48;
                    if(now[i][kk] != rht[i][kk]) mp ++ ;
                }
            rep(i, mp, 16){
                max_deep = i ;
                if (knight(0, mp, -1, stx, sty)){
                    cout << i - 1 << endl;
                    mark = 1 ;
                    break ; 
                }
            }
            if(!mark) cout << -1 << endl ; 
        }
    }
    
    
  • 相关阅读:
    js中==与===区别
    Initialization failure 0x0000000c
    Spring通过@Value注解注入属性的几种方式
    java中读取配置文件中数据的具体方法
    spring整合hibernate
    url上参数解析笔记
    编号的生成(日期+序列号)
    application.xml & -servlet.xml
    webApplicationContext 与servletContext
    Http协议整理
  • 原文地址:https://www.cnblogs.com/pks-t/p/9209676.html
Copyright © 2020-2023  润新知