zoukankan      html  css  js  c++  java
  • [高级搜索]骑士精神

    题目链接

    解题思路

    这道题方法很多。

    我们首先思考一下,这道题只要大于15就输出-1了,然后又要让我们求最小值,显然。可以用迭代加深来搞。

    我们直接枚举最小的步数即可。

    但这样仅仅20分...你想嘛,如果没有任何优化,其实就跟暴力是一样的...在这里,我们引进一个乐观估计函数。

    何为乐观估计函数,其实这道题就是在最优情况下达到目标图的最小步数。

    就是说一定要小于等于实际步数。

    如果当前步数加上乐观估计的步数依旧不行,那么就没必要继续往下面搜索了,很轻松啊。

    其实有些人就会有些疑问,因为有些时候,好像自己打搜索也加了这些优化,但是却是全部都爆了。这很显然....你做的不是搜索题目....但是有剪枝优化的思想还是很好的。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    int n, G[10][10], sx, sy, ans;
    int dir[8][2] = {{1, -2}, {2, -1}, {2, 1}, {1, 2}, {-1, 2}, {-2, 1}, {-2, -1}, {-1, -2}};//方向函数
    int goal[10][10] = {
        {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 check (){//乐观估计函数
        int sum = 0;
        for (int i = 1; i <= 5; i ++){
            for (int j = 1; j <= 5; j ++){
                if (goal[i][j] != G[i][j])
                    sum ++;
            }
        }
        return sum;
    }
    bool pd (int x, int y){
        if (x < 1 || y < 1 || x > 5 || y > 5)
            return 0;
        return 1;
    }
    bool iddfs (int x, int y, int depth, int maxdep){//迭代加深
        if (depth == maxdep){
            if (! check ())
                return 1;
            return 0;
        }
        for (int i = 0; i < 8; i ++){
            int tox = x + dir[i][0];
            int toy = y + dir[i][1];
            if (pd (tox, toy)){
                swap (G[x][y], G[tox][toy]);
                if (check () + depth <= maxdep)
                    if (iddfs (tox, toy, depth + 1, maxdep))
                        return 1;
                swap (G[x][y], G[tox][toy]);
            }
        }
        return 0;
    }
    int main (){
        scanf ("%d", &n);
        while (n --){
            ans = -1;
            for (int i = 1; i <= 5; i ++){
                scanf ("
    ");
                for (int j = 1; j <= 5; j ++){
                    char c;
                    scanf ("%c", &c);
                    if (c == '*')   G[i][j] = 2, sx = i, sy = j;
                    else G[i][j] = c - 48;
                }
            }
            for (int i = 0; i <= 15; i ++){
                if (iddfs (sx, sy, 0, i)){
                    ans = i;
                    break;
                }
            }
            printf ("%d
    ", ans);
        }
        return 0;
    }

    这种方法固然可行,但我们还可用另一种高级搜索的方法。

    题目给出了初始图和目标图,我们知道起点与终点,于是我们就可以用双向BFS,但问题来了,搜索的话我们肯定有些东西是重复进行了搜索,如何避免呢?

    图是一个矩阵,我们不好进行标记,这里,我们就要考虑用到哈希。看原图,除去星号就是由01组成的,可以说是二进制编码。因此呢,我们就可以用二进制来表示。

    但是会有一个问题,那就是不同的图依旧有同样的值。这里我们就需要考虑到星号的坐标,这样我们就可以保证唯一了。

    我们判断一下范围,发现数值刚好卡在int那里,肯定可以算出。于是就可以用map来弄

    但我们是用的2进制编码,这样其实相对来讲很难表示,如果用二维数组的话,则更难弄出来。

    于是呢,我选择暴力。

    我直接用3进制,这样就不会有重复了。

    LL gethash(node a) {
        LL k = 1, ans = 0;
        for (int i = 1; i <= 5; i ++) {
            for (int j = 1; j <= 5; j ++){
                ans += k * a.word[i][j];
                k *= 3;
            }
        }
        return ans;
    }

    没啥好讲的,毕竟是搜索,相信大家都会

    map<LL, edge> vis[2];这样定义好用一些。

  • 相关阅读:
    自定义提示框(alert、confirm 可自定义标题 内容 图标 取消按钮)
    Node.js 技術
    ASP.NET MVC+Spring.net+Nhibernate+EasyUI+Jquery开发案例(1)
    Memcached 命令简介
    MySQL 请选择合适的列
    WCF光芒下的Web Service
    如何实现共享软件网络授权认证,包括注册新用户、登录、修改密码等操作
    SOA面向服务架构简述
    Python Web 框架, 使用 Django 和 Python 开发 Web 站点
    Interface继承至System.Object?
  • 原文地址:https://www.cnblogs.com/lover-fucker/p/13566678.html
Copyright © 2011-2022 走看看