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的值,也可以直接检验当前数组是否合法. # ...
随机推荐
- ZOJ3516 (图的遍历)
Tree of Three Time Limit: 2 Seconds Memory Limit: 65536 KB Now we have a tree and some queries ...
- 关于xhEditor
关于xhEditor xhEditor是一个基于jQuery开发的简单迷你并且高效的在线可视化HTML编辑器,基于网络访问并且兼容IE 6.0+,Firefox 3.0+,Opera 9.6+,Chr ...
- 【刷题 Python Tip】题目6~10
[题目6]输出100以内的所有素数,素数之间以一个空格区分 from math import sqrt print ' '.join(str(key) for key in [x for x in x ...
- 所闻所获5:关于iOS的证书
去年做ondine时,被iOS的证书搞得很是头大,做完了之后感觉一片混乱,印象也不是很深.最近又发布了meditashayne,个人的第二个App,也就重温了一下证书的一些相关操作.这一次的理解比较深 ...
- 带你走近AngularJS - 创建自己定义指令
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自己定义指令 ------------ ...
- Int16 Int32 Int64
数据类型占多大空间 Int16, 等于short, 占2个字节. -32768 32767 Int32, 等于int, 占4个字节. -2147483648 2147483647 Int64, 等于l ...
- JavaScript脚本语言的正则校验法
正则校验法有很多种类型,有些可能会比较复杂难记,我这里罗列了大家常用的几种方法,方便查询. //校验是否全由数字组成 function isShuZi(s) { var patrn=/^[0-9]{1 ...
- ios9基础知识总结(一)
I--load 类被加载时自动调用,只要类的项目中,运行时就会加载.类一加载,此方法就会调用 //类被加载时调用,只要类的项目中,运行时就会加载,类一加载,此方法就调用 + (void)load { ...
- BestCoder 2nd Anniversary 1001 Oracle
找到最小的非零数字拆开来相加. 高精度. #include <iostream> #include <cstdio> #include <cstring> #inc ...
- Android 部分机型GridView四周默认间距
在测试兼容性时候,部分机型,比如联想和一加等手机,在使用Gridview的时候,会默认四周有默认边距,10dp左右. 这时候需要设置 android:listSelector="@andro ...