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

题目大意:

有一个3 * 3 的格子:

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

例如以下图所看到的:

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

如今。给你左右移动的费用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;
}

UVALive 6665 Dragonas Cruller的更多相关文章

  1. UVALive 6665 Dragon’s Cruller --BFS,类八数码问题

    题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...

  2. UVALive - 4108 SKYLINE[线段树]

    UVALive - 4108 SKYLINE Time Limit: 3000MS     64bit IO Format: %lld & %llu Submit Status uDebug ...

  3. UVALive - 3942 Remember the Word[树状数组]

    UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...

  4. UVALive - 3942 Remember the Word[Trie DP]

    UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...

  5. 思维 UVALive 3708 Graveyard

    题目传送门 /* 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000 ...

  6. UVALive 6145 Version Controlled IDE(可持久化treap、rope)

    题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...

  7. UVALive 6508 Permutation Graphs

    Permutation Graphs Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit ...

  8. UVALive 6500 Boxes

    Boxes Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Pract ...

  9. UVALive 6948 Jokewithpermutation dfs

    题目链接:UVALive 6948  Jokewithpermutation 题意:给一串数字序列,没有空格,拆成从1到N的连续数列. dfs. 可以计算出N的值,也可以直接检验当前数组是否合法. # ...

随机推荐

  1. knowledges address

    http://www.zhukun.net/archives/5794

  2. Modulo Sum(背包 + STL)

     Modulo Sum time limit per test 2 seconds memory limit per test 256 megabytes input standard input o ...

  3. .net网站开发(设计):1.什么是MVC模式

    好吧我知道,应该很少人一开始学网站开发就从MVC开始,但如果你已经理解了三层架构之类的,那直接尝试强大的微软MVC网站开发模式也是挺不错的. 但其实我们学校有个实验室,那些干进去的就算是大一的学生,也 ...

  4. Web安全技术(3)-浏览器的跨域访问

    http://www.blogjava.net/linli/archive/2015/04/22/424584.html 一.浏览器介绍 对于Web应用来说,浏览器是最重要的客户端. 目前浏览器五花八 ...

  5. CentOS 5.7 中文乱码问题解决方案

    一.安装中文支持: # yum install "@Chinese Support" 二.用 yum 安装中文字体 #yum install fonts-chinese.noarc ...

  6. (转)android多国语言适配

    android多国语言文件夹 android多国语言文件夹文件汇总如下:(有些语言的书写顺序可能跟中文是相反的) 中文(中国):values-zh-rCN 中文(台湾):values-zh-rTW 中 ...

  7. bootstrap使用中遇到的问题(二)

    1.ie8不支持carousel组件, 解决方法:将jquery换为jquery1版本,具体原因不清楚~~~~~ 2.ie8不支持background-color:rgba(); 解决方法:这样写代码 ...

  8. ASP.NET,Razor语句中@符号的意义

    比较下面两段代码的区别: <td> @if (item.ModifyTime.HasValue) { @item.ModifyTime.GetValueOrDefault().ToStri ...

  9. JAVA异常使用_每个人都曾用过、但未必都用得好

    一.抛出异常 vs. 返回错误代码 有人说“Well, an exception is a goto.”,但也有人言“makes the code simpler by visibly separat ...

  10. 设计师如何为 Android 应用标注尺寸

    http://blog.cutterman.cn/?p=33 1. 画布大小定位 720 x 1280,72 dpi2. 只使用偶数单位的尺寸,比如 96 px 的列表项高度,16 px 的边距,64 ...