hihoCoder 1312:搜索三·启发式搜索(A* + 康托展开)
题意
中文题意
思路
做这题的前置技能学习
康托展开
这个东西我认为就是在排列组合问题上的Hash算法,可以压缩空间。A*搜索。
这里我使用了像k短路一样的做法,从最终状态倒回去预处理一遍距离,但是跑了0.8s,可能是预处理花费的时间太多了。有些人用曼哈顿距离估价,跑了0.2s。
#include <bits/stdc++.h>
using namespace std;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;
typedef long long LL;
struct Node {
    int x, y, f, g, kt, mm[4][4];
    bool operator < (const Node &rhs) const {
        return f > rhs.f;
    }
};
int init[4][4] = {
    { 1, 2, 3 },
    { 4, 5, 6 },
    { 7, 8, 0 }
};
int mp[4][4], ans, h[500001], vis[500001], target;
int f[10], dx[] = {0, 0, 1, -1}, dy[] = {1, -1, 0, 0};
int kangtuo(int mp[4][4]) {
    int sum = 0;
    for(int i = 0; i < 9; i++) {
        int now = 0;
        for(int j = i + 1; j < 9; j++) {
            if(mp[i/3][i%3] > mp[j/3][j%3]) now++;
        }
        sum += now * f[9-i-1];
    } return sum + 1;
}
void BFS(int x, int y) {
    memset(h, INF, sizeof(h));
    queue<Node> que;
    Node now = (Node) {x, y, 0, 0};
    for(int i = 0; i < 3; i++) for(int j = 0; j < 3; j++)
        now.mm[i][j] = init[i][j];
    h[target] = 0;
    que.push(now);
    while(!que.empty()) {
        Node now = que.front(); que.pop();
        int x = now.x, y = now.y, f = now.f;
        for(int i = 0; i < 4; i++) {
            now.x = x + dx[i], now.y = y + dy[i];
            if(now.x < 0 || now.x > 2 || now.y < 0 || now.y > 2) continue;
            swap(now.mm[x][y], now.mm[now.x][now.y]);
            int nf = f + 1, nkt = kangtuo(now.mm);
            now.f = nf;
            if(h[nkt] == INF) {
                h[nkt] = nf;
                que.push(now);
            }
            swap(now.mm[x][y], now.mm[now.x][now.y]);
        }
    }
}
void YCL() {
    BFS(2, 2);
}
int Astar(int x, int y) {
    priority_queue<Node> que;
    memset(vis, 0, sizeof(vis));
    vis[kangtuo(mp)] = 1;
    Node now = (Node) { x, y, 0, 0, kangtuo(mp)};
    for(int i = 0; i < 3; i++)
        for(int j = 0; j < 3; j++)
            now.mm[i][j] = mp[i][j];
    que.push(now);
    while(!que.empty()) {
        now = que.top(); que.pop();
        int x = now.x, y = now.y, f = now.f, g = now.g, kt = now.kt;
        if(kt == target) return f;
        for(int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if(nx < 0 || nx > 2 || ny < 0 || ny > 2) continue;
            swap(now.mm[x][y], now.mm[nx][ny]);
            int nkt = kangtuo(now.mm);
            now.x = nx, now.y = ny, now.g = g + 1, now.f = now.g + h[nkt], now.kt = nkt;
            if(!vis[nkt]) {
                vis[nkt] = 1;
                que.push(now);
            }
            swap(now.mm[x][y], now.mm[nx][ny]);
        }
    } return -1;
}
int main() {
    f[0] = 1;
    for(int i = 1; i < 9; i++) f[i] = f[i-1] * (i);
    target = kangtuo(init);
    YCL();
    int t; scanf("%d", &t);
    while(t--) {
        int ix, iy;
        for(int i = 0; i < 3; i++)
            for(int j = 0; j < 3; j++) {
                scanf("%d", &mp[i][j]);
                if(mp[i][j] == 0) ix = i, iy = j;
            }
        ans = Astar(ix, iy);
        if(~ans) printf("%d\n", ans);
        else puts("No Solution!");
    }
    return 0;
}
												
											hihoCoder 1312:搜索三·启发式搜索(A* + 康托展开)的更多相关文章
- hihoCoder #1312 : 搜索三·启发式搜索(A*, 康托展开)
		
原题网址:http://hihocoder.com/problemset/problem/1312 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 在小Ho的手机上有 ...
 - 【hihocoder 1312】搜索三·启发式搜索(启发式搜索写法)
		
[题目链接]:http://hihocoder.com/problemset/problem/1312?sid=1092363 [题意] [题解] 定义一个A*函数 f = step+val 这里的v ...
 - 【hihocoder 1312】搜索三·启发式搜索(普通广搜做法)
		
[题目链接]:http://hihocoder.com/problemset/problem/1312?sid=1092352 [题意] [题解] 从末状态的123456780开始逆向搜; 看它能到达 ...
 - hdu 1430(BFS+康托展开+映射+输出路径)
		
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
 - 康托展开:对全排列的HASH和还原,判断搜索中的某个排列是否出现过
		
题目:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2297 前置技能:(千万注意是 ...
 - 双向广搜+hash+康托展开  codevs 1225 八数码难题
		
codevs 1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启 ...
 - HDU 1430 魔板(康托展开+BFS+预处理)
		
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
 - hdu1430魔板(BFS+康托展开)
		
做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...
 - poj1077(康托展开+bfs+记忆路径)
		
题意:就是说,给出一个三行三列的数组,其中元素为1--8和x,例如: 1 2 3 现在,需要你把它变成:1 2 3 要的最少步数的移动方案.可以右移r,左移l,上移u,下移dx 4 6 4 5 67 ...
 
随机推荐
- MVC 身份验证和异常处理过滤器
			
:在Global中注册为全局过滤器,应用于所有的Controller的Action 参数类均继承自ControllerContext,主要包含属性请求上下文.路由数据.结果 using FilterE ...
 - c# 编写REST的WCF
			
REST(Representational State Transfer)即 表述性状态传递 ,简称REST,通俗来讲就是:资源在网络中以某种表现形式进行状态转移. RESTful是一种软件架构风格. ...
 - 请求通道在等待 00:00:58.9616639 以后答复时超时。增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值。分配给此操作的时间可能是更长超时的一部分。
			
异常信息:请求通道在等待 00:00:58.9616639 以后答复时超时.增加传递给请求调用的超时值,或者增加绑定上的 SendTimeout 值.分配给此操作的时间可能是更长超时的一部分. 开发背 ...
 - Android 动画基础——视图动画(View Animation)
			
本篇讲android 3.0之前被广泛的动画框架——ViewAnimation. 目录 我将分为六部分来讲: 概述 Alpha透明动画 Rotate旋转动画 Translate位移动画 Scale放缩 ...
 - Unicode 7.0.1中文支持非常好
			
简单测试了一下,7.0.1中文支持非常好.Delphi7下将UniConnection的useUnicode设置为False,Tokyo下设置为True,Charset空着即可. 问题要点:1.建数据 ...
 - UILabel实现自适应宽高需要注意的地方
			
需求如下: 需要显示2行文字,宽度为 SCREEN_Width - 40 高度为两行文本的自适应高度 需要在此UILabel 下面添加imageView , 因此UIlabel 的高度需要准确,不 ...
 - 【图文】[新手]C++ 动态库导出函数名“乱码”及解决
			
刚接触C++,在尝试从 dll 中导出函数时,发现导出的函数名都"乱码"了. 导出过程如下: 新建一个Win32项目: 新建的解决方案里有几个导出的示例: // 下列 ifdef ...
 - 前端  JS 修炼(第一天)包装对象、作用域、创建对象
			
1.js基本概念以及注意 直接量 :程序中直接使用的数据值.下面列出的都是直接量: 1 12 //数字 2 1.2 //小数 3 "hello world" //字符串文本 4 t ...
 - .NET程序员如何快入门Spring Boot
			
本篇文章将教你作为一个.NET程序员如何快入门Spring Boot.你不需要用Eclipse,也不需要用IDEA.已经习惯了VS,其他的IDE-- 但不得不说VS Code很厉害,一用就喜欢.微软给 ...
 - echarts 中国地图标注所在点
			
达到的效果: 1.本身是个中国地图‘ 2.直接通过经纬度标注 3.标注点可以是其他样子(比如:五角星) 4.标注点具有提示框并且鼠标可以进入 5.提示框里的链接可点击(可以添加为链接事件): 所需要技 ...