UVALive 6665 Dragonas Cruller[通俗易懂]

UVALive 6665 Dragonas Cruller

大家好,又见面了,我是全栈君。

题目链接:https://icpcarchive.ecs.baylor.edu/external/66/6665.pdf

题目大意:

有一个3 * 3 的格子:

UVALive 6665 Dragonas Cruller[通俗易懂]

UVALive 6665 Dragonas Cruller[通俗易懂]

每个格子上面的数字能够朝上下左右四个方向移动。假设移出范围。则到与其边界上字母相应的还有一边。

例如以下图所看到的:

UVALive 6665 Dragonas Cruller[通俗易懂]

UVALive 6665 Dragonas Cruller[通俗易懂]

空白部分分别向上下左右移动之后的情况。

如今。给你左右移动的费用ch,上下移动cv。给你一个初始状态(9个数字,当中0代表该空格为空),一个结束状态,问从初始状态移动到结束状态的最小花费。

解题思路:

事实上这道题想法非常easy,简单的bfs + 优先队列。主要是细节处理方面比較麻烦。

把上述九宫格变为一个序列,会发现状态最多就9!种,所以状态能够依照序列的排序离散化。详细參考代码。

然后改成序列之后,会发现左右移动事实上就是 i + 1。 i – 1的操作。上下移动是 i + 3, i – 3 的操作。

代码:

#include<map>
#include<set>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<fstream>
#include<cstring>
#include<ctype.h>
#include<iostream>
#include<algorithm>
#define maxn 1000
#define INF (1<<30)
#define PI acos(-1.0)
#define mem(a, b) memset(a, b, sizeof(a))
#define For(i, n) for (int i = 0; i < n; i++)
#define debug puts("===============")
const int N = 362881;
typedef long long ll;
using namespace std;
int ch, cv;
int fac[10];
struct node {
    int x, w;
    node(int _x, int _w) {
        x = _x, w = _w;
    }
    bool operator < (const node & T) const {
        return w > T.w;
    }
};
void Atoint(int* a, int &x) {
    int i, j, y;
    x = 0;
    for (i = 0; i < 9; i++) {
        y = a[i];
        for (j = 0; j < i; j++)
            if (a[j] < a[i]) y--;
        x += fac[8 - i] * y;
    }
}
void inttoA(int x, int* a) {
    int has[10] = {0};
    int i, j, y;
    for (i = 0; i < 9; i++) {
        y = x / fac[8 - i];
        for (j = 0; j < 9; j++) if (!has[j]) {
            if (y == 0) break;
            y--;
        }
        a[i] = j, has[j] = 1, x %= fac[8 - i];
    }
}
int st, ed;
priority_queue<node> q;
int d[N], vis[N], a[10], b[10];
void update(int x, int w) {
    if (!vis[x] && d[x] > w) {
        d[x] = w, q.push(node(x, w));
    }
}
void work() {
    Atoint(a, st), Atoint(b, ed);
    while(!q.empty()) q.pop();
    memset(d, 0x7F, sizeof(d));
    memset(vis, 0, sizeof(vis));
    d[st] = 0;
    q.push(node(st, 0));
    int x, w, i, y;
    while(!q.empty()) {
        x = q.top().x, w = q.top().w, q.pop();
        if (vis[x]) continue;
        vis[x] = 1;
        if (x == ed) {
            printf("%d\n", w);
            break;
        }
        inttoA(x, a);
        for (i = 0; i < 9; i++) if (!a[i]) break;
        swap(a[i], a[(i + 1) % 9]);
        Atoint(a, y);
        update(y, w + ch);
        swap(a[i], a[(i + 1) % 9]);
        swap(a[i], a[(i + 8) % 9]);
        Atoint(a, y);
        update(y, w + ch);
        swap(a[i], a[(i + 8) % 9]);
        swap(a[i], a[(i + 3) % 9]);
        Atoint(a, y);
        update(y, w + cv);
        swap(a[i], a[(i + 3) % 9]);
        swap(a[i], a[(i + 6) % 9]);
        Atoint(a, y);
        update(y, w + cv);
    }
}
int main () {
    //freopen("1.txt", "r", stdin);
    fac[0] = 1;
    for (int i = 1; i < 10; i++) fac[i] = fac[i - 1] * i;
    while(scanf("%d%d", &ch, &cv), ch || cv) {
        for (int i = 0; i < 9; i++) scanf("%d", a + i);
        for (int i = 0; i < 9; i++) scanf("%d", b + i);
        work();
    }
    return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115862.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • js原生判断是否是数字类型[通俗易懂]

    js原生判断是否是数字类型[通俗易懂]js判断数字类型汇总最近在写代码的时候,有些逻辑需要判断数字类型,等用到的时候才发现自己了解的方法不太严密,然后就决心查资料汇总了解下有哪些方法比较严密第一种:typeof+isNaN使用typeof可以判断是否是一个数字类型,但是NaN也是数字类型,为了筛除这个可能,进一步通过isNaN来筛除。这种方法会遗漏InfinityfunctionisNumber(num){ retu…

    2022年6月28日
    22
  • 走近webpack(3)–图片的处理[通俗易懂]

    上一章,咱们学了如何用webpack来打包css,压缩js等。这一篇文章咱们来学习一下如何用webpack来处理图片。废话不多说,咱们开始吧。首先,咱们随便找一张你喜欢的图片放到src/images

    2022年3月25日
    48
  • turtle(海龟作图),C++版「建议收藏」

    turtle(海龟作图),C++版「建议收藏」海龟作图引言turtle来源Logo的原型来自另一个计算机语言LISP,派普特修改了LISP的语法使其更易于阅读。Logo常被称作没有括号的Lisp。Logo是一种解释型语言,和其他语言不同的是,它内置一套海龟绘图(TurtleGraphics)系统,通过向海龟发送命令,用户可以直观地学习程序的运行过程,因此很适于儿童学习。它亦适合用作数学教学。海龟绘图使得Logo用户可以通过简单的编程创作出丰富多彩的视觉效果或图案。假想一只带着画笔的海龟可以接受简单的命令,例如向前走100步,或者左转30度。

    2022年6月28日
    50
  • 【18】进大厂必须掌握的面试题-15个Kafka面试

    【18】进大厂必须掌握的面试题-15个Kafka面试

    2020年11月14日
    217
  • 从中国历年人口数据简单分析未来房价走势(本分析仅供参考)

    从中国历年人口数据简单分析未来房价走势(本分析仅供参考)以下数据来自中国统计局官方网站从1981-1997的连续17年,中国每年人口净出生人口都在2000万以上。从1998年开始,逐年减少,从2001年开始至2017年,每年净出生人口基本在1600万左右。所以在最近十五年,正是赶上1981-1997出生的这一波人要买房,因此把房价无情地快速推高。随着这批人买房需求的满足,房屋需求开始下降,这也解释了为什么这几年一直有人在喊房价要降,并且…

    2022年9月5日
    3
  • 第十七篇:实例分析(1)–初探WDDM驱动学习笔记(八)

    第十七篇:实例分析(1)–初探WDDM驱动学习笔记(八)

    2022年1月23日
    65

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号