魔板

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2921    Accepted Submission(s): 649

Problem Description
在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板。魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示。任一时刻魔板的状态可用方块的颜色序列表示:从魔板的左上角开始,按顺时针方向依次写下各方块的颜色代号,所得到的数字序列即可表示此时魔板的状态。例如,序列(1,2,3,4,5,6,7,8)表示魔板状态为:

1 2 3 4
8 7 6 5

对于魔板,可施加三种不同的操作,具体操作方法如下:

A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368

给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。

 
Input
每组测试数据包括两行,分别代表魔板的初态与目态。

 
Output
对每组测试数据输出满足题意的变换步骤。

 
Sample Input
12345678
17245368
12345678
82754631
 
Sample Output
C
AC

题目链接:HDU 1430

原来思路是就用康托展开映射然后每一次都从S搜索到T然而T了。

然后改为预处理,从12345678开始把其他状态全部搜完并记录,O(1)输出,但是由于一开始的S不一定是12345678,因此要用一个映射数组refl[]来记录S与12345678的关系,然后根据这个关于把T也转换成相对应的关系,之后还是WA很久,后来发现是第二种变化的后半部分循环反了(囧)……

按照A、B、C的顺序变化使得达到的某一状态都是最优解即长度最小的情况下字典序也最小(也可以用优先队列来实现就是速度慢了点),然后加了个没什么用的剪枝防止出现AA、BBBB、CCCC这样又变回原来状态的无意义操作。把康托展开写在结构体里简直方便的不行……

给一组测试数据

63728145
86372541

ACBBBCBBCBCBCABB

这组能过的话基本上就可以A了

代码:

#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
using namespace std;
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
typedef pair<int,int> pii;
typedef long long LL;
const double PI=acos(-1.0);
const int N=40320+10;
int fact[9]={1,1,2,6,24,120,720,5040,40320};
struct info
{
int arr[8];
int val;
string step;
void cantor()
{
val=0;
for (int i=0; i<8; ++i)
{
int k=0;
for (int j=i+1; j<8; ++j)
{
if(arr[j]<arr[i])
++k;
}
val+=k*fact[7-i];
}
}
void change_A()
{
reverse(arr,arr+8);
step+="A";
}
void change_B()
{
int temp=arr[3];
for (int i=3; i>0; --i)
arr[i]=arr[i-1];
arr[0]=temp; temp=arr[4];
for (int i=4; i<7; ++i)
arr[i]=arr[i+1];
arr[7]=temp;
step+="B";
}
void change_C()
{
int temp=arr[2];
arr[2]=arr[1];
arr[1]=arr[6];
arr[6]=arr[5];
arr[5]=temp;
step+="C";
}
};
info S,T;
char s[10];
int vis[N];
string ans[N];
int refl[10];
void bfs()
{
CLR(vis,0);
queue<info>Q;
vis[S.val]=1;
Q.push(S);
info now,v;
while (!Q.empty())
{
now=Q.front();
Q.pop();
int len=(int)now.step.length();
if(len<1||now.step[len-1]!='A')
{
v=now;
v.change_A();
v.cantor();
if(!vis[v.val])
{
vis[v.val]=1;
ans[v.val]=v.step;
Q.push(v);
}
}
if(len<3||now.step[len-1]!='B'||now.step[len-2]!='B'||now.step[len-3]!='B')
{
v=now;
v.change_B();
v.cantor();
if(!vis[v.val])
{
vis[v.val]=1;
ans[v.val]=v.step;
Q.push(v);
}
}
if(len<3||now.step[len-1]!='C'||now.step[len-2]!='C'||now.step[len-3]!='C')
{
v=now;
v.change_C();
v.cantor();
if(!vis[v.val])
{
vis[v.val]=1;
ans[v.val]=v.step;
Q.push(v);
}
}
}
}
int main(void)
{
int i;
for (i=0; i<8; ++i)
S.arr[i]=i+1;
S.cantor(); bfs(); while (~scanf("%s",s))
{
for (i=0; i<8; ++i)
refl[s[i]-'0'-1]=i+1; scanf("%s",s);
for (i=0; i<8; ++i)
T.arr[i]=refl[s[i]-'0'-1];
T.cantor(); printf("%s\n",ans[T.val].c_str());
}
return 0;
}

HDU 1430 魔板(康托展开+BFS+预处理)的更多相关文章

  1. hdu 1430 魔板 康托展开 + 很好的映射

    http://acm.hdu.edu.cn/showproblem.php?pid=1430 如果从start ---> end,每一次都bfs进行,那么就肯定会超时. 考虑到先把start映射 ...

  2. HDU - 1430 魔板 【BFS + 康托展开 + 哈希】

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...

  3. hdu.1430.魔板(bfs + 康托展开)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submis ...

  4. HDU - 1430 魔板 (bfs预处理 + 康托)

    对于该题可以直接预处理初始状态[0, 1, 2, 3, 4, 5, 6, 7]所有可以到达的状态,保存到达的路径,直接打印答案即可. 关于此处的状态转换:假设有初始状态为2,3,4,5,0,6,7,1 ...

  5. HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)

    Eight Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30176   Accepted: 13119   Special ...

  6. [HDU 1430] 魔板

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  7. hdu 1430 魔板 (BFS+预处理)

    Problem - 1430 跟八数码相似的一题搜索题.做法可以是双向BFS或者预处理从"12345678"开始可以到达的所有状态,然后等价转换过去直接回溯路径即可. 代码如下: ...

  8. hdu1430 魔板(康拓展开 bfs预处理)

    魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  9. HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3

    http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...

随机推荐

  1. 传染病控制(codevs 1091)

    题目描述 Description [问题背景] 近来,一种新的传染病肆虐全球.蓬莱国也发现了零星感染者,为防止该病在蓬莱国 大范围流行,该国政府决定不惜一切代价控制传染病的蔓延.不幸的是,由于人们尚未 ...

  2. Android 如何让EditText不自动获取焦点

    解决之道:在EditText的父级控件中找一个,设置成 android:focusable="true"     android:focusableInTouchMode=&quo ...

  3. AsyncHttpClient

    package com.jingle.httpstudy;   import org.apache.http.Header;   import android.app.Activity; import ...

  4. Jil序列化JSON

    使用Jil序列化JSON提升Asp.net web api 性能   JSON序列化无疑是Asp.net web api 里面性能提升最重要的一环. 在Asp.net web api 里面我们可以插入 ...

  5. Laravel 4 系列入门教程(一)

    默认条件 本文默认你已经有配置完善的PHP+MySQL运行环境,懂得PHP网站运行的基础知识.跟随本教程走完一遍,你将会得到一个基础的包含登录的简单blog系统,并将学会如何使用一些强大的Larave ...

  6. poj 2195 二分图带权匹配+最小费用最大流

    题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目 ...

  7. 用VMware9 安装 mac 10.8和10.9搜集的资料

    VMware9虚拟机安装MAC OS X Mountain Lion 10.8.2详细图文教程 http://diybbs.zol.com.cn/1/34037_699.html vmware too ...

  8. Codeforces Gym 100637A A. Nano alarm-clocks 前缀和处理

    A. Nano alarm-clocks Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100637/p ...

  9. java抽象类的使用

    当多个类中出现相同功能,但是功能主体不同,这是可以进行向上抽取.这时,只抽取功能定义,而不抽取功能主体. 抽象:看不懂. 抽象类的特点:1,抽象方法一定在抽象类中.2,抽象方法和抽象类都必须被abst ...

  10. TeeChart注册方法