UVALive 6665 Dragonas Cruller
题目链接: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的更多相关文章
- UVALive 6665 Dragonâs Cruller --BFS,类八数码问题
题意大概就是八数码问题,只不过把空格的移动方式改变了:空格能够向前或向后移动一格或三格(循环的). 分析:其实跟八数码问题差不多,用康托展开记录状态,bfs即可. 代码: #include <i ...
- UVALive - 4108 SKYLINE[线段树]
UVALive - 4108 SKYLINE Time Limit: 3000MS 64bit IO Format: %lld & %llu Submit Status uDebug ...
- UVALive - 3942 Remember the Word[树状数组]
UVALive - 3942 Remember the Word A potentiometer, or potmeter for short, is an electronic device wit ...
- UVALive - 3942 Remember the Word[Trie DP]
UVALive - 3942 Remember the Word Neal is very curious about combinatorial problems, and now here com ...
- 思维 UVALive 3708 Graveyard
题目传送门 /* 题意:本来有n个雕塑,等间距的分布在圆周上,现在多了m个雕塑,问一共要移动多少距离: 思维题:认为一个雕塑不动,视为坐标0,其他点向最近的点移动,四舍五入判断,比例最后乘会10000 ...
- UVALive 6145 Version Controlled IDE(可持久化treap、rope)
题目链接:https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- UVALive 6508 Permutation Graphs
Permutation Graphs Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit ...
- UVALive 6500 Boxes
Boxes Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Pract ...
- UVALive 6948 Jokewithpermutation dfs
题目链接:UVALive 6948 Jokewithpermutation 题意:给一串数字序列,没有空格,拆成从1到N的连续数列. dfs. 可以计算出N的值,也可以直接检验当前数组是否合法. # ...
随机推荐
- 数据挖掘经典算法之KNN
KNN也称为k近邻算法,本质思想:物以类聚. 在分类或者预测中,待分类或预测的样本的类别和走势将直接参考与该样本最“近邻”的k个邻居. 在这种思路下,KNN注定会遇到3个问题: (1): 谁是我的邻居 ...
- 【转】android 电容屏(二):驱动调试之基本概念篇
关键词:android 电容屏 tp 工作队列 中断 多点触摸协议平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV310(samsung ...
- Python re模块 正则表达式
1 简介 就其本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现.正则表达式模式被编译成一系列的字节码,然后由用 C ...
- IOS 网络判断
Reachability *connectionNetWork= [Reachability reachabilityForInternetConnection] ; int status = [co ...
- C#向文件写、读数据
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- LeetCode OJ平台上Maximum Subarray题目O(n)复杂度解决方式
原始题目例如以下,意为寻找数组和最大的子串,返回这个最大和就可以. Find the contiguous subarray within an array (containing at least ...
- Javascript进阶篇——(数组)笔记整理
什么是数组数组是一个值的集合,每个值都有一个索引号,从0开始,每个索引都有一个相应的值,根据需要添加更多数值. <script type="text/javascript"& ...
- node.js实践第二天
使用Express框架搭建一个网站 1.安装Express 首先要用全局模式安装Express,因为只有这样才能在命令行中使用它.使用下述命令在伪dos命令窗口安装express. $ npm ins ...
- mvc 客户端验证
@model MvcApplication1.Models.ViewClass @{ ViewBag.Title = "View2"; } @******引用这两个js实现客户端的 ...
- 动态链接库的生成(dll)和 动态链接库隐式and显式调用
一.构建动态链接库(dll.dll dll.lib dll.h) 说明: .dll 是在执行程序是调用 .lib 是在连接程序是调用 .h是在编译程序时调用 1.头文件(声明导入函数):_decl ...