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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 数据库中varchar类型 最大长度是多少?[通俗易懂]

    数据库中varchar类型 最大长度是多少?[通俗易懂]一.varchar存储规则:4.0版本以下,varchar(20),指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节)5.0版本以上,varchar(20),指的是20字符,无论存放的是数字、字母还是UTF8汉字(每个汉字3字节),都可以存放20个,最大大小是65532字节Mysql4中最大也不过是20个字节,但是Mysql5根据编码不同,存储大小也不同。…

    2022年4月19日
    1.3K
  • mysql中not exists用法_not exists用法

    mysql中not exists用法_not exists用法notexists是sql中的一个语法,常用在子查询和主查询之间,用于条件判断,根据一个条件返回一个布尔值,从而来确定下一步操作如何进行,notexists也是exists或in的对立面。notexists是exists的对立面,所以要了解notexists的用法,我们首先了解下exists、in的区别和特点:exists:强调的是是否返回结果集,不要求知道返回什么,比如:sele…

    2022年7月15日
    13
  • Tortoise小乌龟SVN回滚到之前的提交版本,即如何撤销此次提交操作

    Tortoise小乌龟SVN回滚到之前的提交版本,即如何撤销此次提交操作

    2021年7月18日
    75
  • JAVA string转map_java怎么转业务

    JAVA string转map_java怎么转业务String转Mapstring转map的时候,很多新人可能不会去判断string的内容是什么格式的,因为map是key-value格式的,但是string就是一个字符串,想想,这个应该不能转吧,我就遇到过,想想就觉得自己傻傻的,哈哈哈。看代码 Stringcontent=””;HashMap<String,Object>map=newHashMap<>();try{map=JS

    2025年10月24日
    4
  • java中怎么输入数组_java中如何从键盘输入数组

    java中怎么输入数组_java中如何从键盘输入数组相关知识说明:java.util.Scanner是Java5的新特征,我们可以通过Scanner类来获取用户的输入。nextLine()函数:1、以Enter为结束符,也就是说nextLine()方法返回的是输入回车之前的所有字符。2、可以获得空白。在线视频教程分享:java在线学习示例如下:publicclassexchangeNum{publicstaticvoidma…

    2022年6月26日
    34

发表回复

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

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