hdu1430魔板
1 2 3 4
8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
由于刚做完八数码问题,再来做这题,认为非常简单。可是用bfs超时(原因是多组数据,太多的数据将程序拖到超时),用dbfs就一直wa(原来是反向的搜索不能保证后半段的字典序最小,只能保证后半段的逆序的字典序最小),所以就得不到正确结果。
百度了一下,原来使用映射+bfs预处理的方法解决的,这样,再多组数据也不怕了。
将任意的初始状态映射为12345678,在这个过程中得到一个映射函数,目标状态根据这个映射函数,映射为相应的目标状态。(这样子能得到正确答案的原因是,魔板的变换,其实只是位置的变换,数字只是用来标记位置的而已,通过同一种映射关系将初始和目标状态的标记同时该改变,所以仍然能得到正确答案)
那么所有的数据,都能转化为初始状态为12345678的搜索,那么只要一遍bfs搜索出12345678所有能到达的状态,并记录步骤即可。
#include <stdio.h>
#include <string.h>
#include <queue>
#include <string>
#include <iostream>
using namespace std;
char st[],ed[];
int vis[];
string ans[];
int fac[] = {,,,,,,,,};
int getHash(char *str)//康托展开
{
int i,j,hash = ,cnt;
for(i=; i<; ++i)
{
cnt = ;
for(j=i+; j<; ++j)
if(str[j]<str[i])
cnt++;
hash += cnt * fac[-i-];
}
return hash;
}
struct node
{
char str[];
};
int d[][] = {{,,,,,,,},{,,,,,,,},{,,,,,,,}};
char change[]; void bfs()
{
queue<node> q;
node cur,tmp;
int i,j;
for(i=; i<; ++i)
cur.str[i] = i + '';
int hash = getHash(cur.str);
q.push(cur);
vis[hash] = true;
q.push(cur);
while(!q.empty())
{
cur = q.front(); q.pop();
int pHash = getHash(cur.str);
for(i=; i<; ++i)
{
for(j=; j<; ++j)
tmp.str[j] = cur.str[d[i][j]];
hash = getHash(tmp.str);
if(vis[hash]) continue;
vis[hash] = true;
ans[hash] = ans[pHash] + (char)('A' + i);
q.push(tmp);
}
}
} int main()
{
bfs();
int i;
while(scanf("%s%s",st,ed)!=EOF)
{
for(i=; i<; ++i)
change[st[i]-''] = i+'';//得到映射函数
for(i=; i<; ++i)
ed[i] = change[ed[i]-''];//根据映射函数改变目标状态
int hash = getHash(ed);
cout<<ans[hash]<<endl;
}
return ;
}
hdu1430魔板的更多相关文章
- hdu1430魔板(BFS+康托展开)
做这题先看:http://blog.csdn.net/u010372095/article/details/9904497 Problem Description 在魔方风靡全球之后不久,Rubik先 ...
- hdu1430 魔板(康拓展开 bfs预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- hdu-1430 魔板 康拓展开+映射优化
给定三种操作,将排列A转化为排列B,求最少步骤. 这种题目可以只跑一次bfs,比如只跑"12345678",那么如果遇到"23456781"->某个字符串 ...
- HDU1430;魔板(BFS+康托展开)
传送门 题意 给出初始序列与终止序列,给出三种操作,问最少经过几次操作能使初始->终止,输出操作(字典序最小) 分析 字符串只有8个字符,使用康托展开. 1.BFS将所有序列从"123 ...
- ACM-康托展开+预处理BFS之魔板——hdu1430
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- Sicily 1051: 魔板(BFS+排重)
相对1150题来说,这道题的N可能超过10,所以需要进行排重,即相同状态的魔板不要重复压倒队列里,这里我用map储存操作过的状态,也可以用康托编码来储存状态,这样时间缩短为0.03秒.关于康托展开可以 ...
- Sicily 1150: 简单魔板(BFS)
此题可以使用BFS进行解答,使用8位的十进制数来储存魔板的状态,用BFS进行搜索即可 #include <bits/stdc++.h> using namespace std; int o ...
- hdu.1430.魔板(bfs + 康托展开)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU 1430 魔板(康托展开+BFS+预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
随机推荐
- mongodb查询分页优化
要求不用skip 前提:1.时间倒序排列(自己现在的项目中也是按照时间倒序排列的) 2.每页显示10条数据 int limit = 10;//刚开始点击查询的时候设置十条 查询形式为 db ...
- oracle检查点队列与增量检查点【转载】
oracle检查点队列与增量检查点 今天是2013-09-04,这几天一直心里安顿不下来,今天还好了,可以自己安静的学习一下oracle,在此记录一下学习笔记.这篇文章我不知道在那转载的,一直都留在我 ...
- [Android学习笔记]获取view的尺寸和坐标
对于UI方面很多时候需要获取它的很多信息,具体情况见view的文档 View文档 http://developer.android.com/training/index.html 常用方法:获取vie ...
- fragment Trying to instantiate a class com.example.testhuanxindemo.MyFragment that is not a Fragmen
在使用fragment的时候,先创建了一个fragment,然后为他创建布局,并在oncreateview中返回载入该视图的后返回的view,在activity的布局文件里,使用xml布局,用frag ...
- Java并发编程--Fork/Join框架使用
上篇博客我们介绍了通过CyclicBarrier使线程同步,可是上述方法存在一个问题,那就是假设一个大任务跑了2个线程去完毕.假设线程2耗时比线程1多2倍.线程1完毕后必须等待线程2完毕.等待的过程线 ...
- Android APP代码拨打电话、打开手机分享功能等隐式意图
Android APP拨打电话: Intent intent=new Intent(Intent.ACTION_DIAL,Uri.parse("tel:"+110)); start ...
- TR90眼镜_百度百科
TR90眼镜_百度百科 TR90眼镜
- 2013 吉林通化邀请赛 D-City 离线型的并查集
题意:给定n个点和m条边,问你拆掉前i条边后,整个图的连同城市的数量. i从1到m. 思路:计算连通的城市,很容易想到并查集,但是题目里是拆边,所以我们可以反向去做. 存下拆边的信息,从后往前建边. ...
- TCP关闭过程
状态迁移 . SO_LINGER/ SO_REUSEADDR TCP正常的关闭过程如下(四次握手过程): (FIN_WAIT_1) A ---FIN---> B(CLOSE_WAIT) (FIN ...
- Spring集成XFire开发WebService
Spring是眼下最流行的JavaEE Framework,可是使用Spring的Spring-WS开发WebService却十分繁琐.XFire是一个简化WebService开发的开源项目.通过Sp ...