HDU 1430 魔板(康托展开+BFS+预处理)
魔板
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2921 Accepted Submission(s): 649
1 2 3 4
8 7 6 5
对于魔板,可施加三种不同的操作,具体操作方法如下:
A: 上下两行互换,如上图可变换为状态87654321
B: 每行同时循环右移一格,如上图可变换为41236785
C: 中间4个方块顺时针旋转一格,如上图可变换为17245368
给你魔板的初始状态与目标状态,请给出由初态到目态变换数最少的变换步骤,若有多种变换方案则取字典序最小的那种。
题目链接: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+预处理)的更多相关文章
- hdu 1430 魔板 康托展开 + 很好的映射
http://acm.hdu.edu.cn/showproblem.php?pid=1430 如果从start ---> end,每一次都bfs进行,那么就肯定会超时. 考虑到先把start映射 ...
- HDU - 1430 魔板 【BFS + 康托展开 + 哈希】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1430 思路 我刚开始 想到的 就是 康托展开 但是这个题目是 多组输入 即使用 康托展开 也是会T的 ...
- hdu.1430.魔板(bfs + 康托展开)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submis ...
- HDU - 1430 魔板 (bfs预处理 + 康托)
对于该题可以直接预处理初始状态[0, 1, 2, 3, 4, 5, 6, 7]所有可以到达的状态,保存到达的路径,直接打印答案即可. 关于此处的状态转换:假设有初始状态为2,3,4,5,0,6,7,1 ...
- HDU 1043 & POJ 1077 Eight(康托展开+BFS+预处理)
Eight Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30176 Accepted: 13119 Special ...
- [HDU 1430] 魔板
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- hdu 1430 魔板 (BFS+预处理)
Problem - 1430 跟八数码相似的一题搜索题.做法可以是双向BFS或者预处理从"12345678"开始可以到达的所有状态,然后等价转换过去直接回溯路径即可. 代码如下: ...
- hdu1430 魔板(康拓展开 bfs预处理)
魔板 Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...
- HDU 3567 Eight II 打表,康托展开,bfs,g++提交可过c++不可过 难度:3
http://acm.hdu.edu.cn/showproblem.php?pid=3567 相比Eight,似乎只是把目标状态由确定的改成不确定的,但是康托展开+曼哈顿为h值的A*和IDA*都不过, ...
随机推荐
- [MAC] 在标题栏上显示目录完整路径
转载自 :http://www.cnblogs.com/yipu/archive/2013/03/13/2956957.html 当我们使用Finder浏览文件的时候,当前目录的名字会显示在标题栏顶端 ...
- static_cast, dynamic_cast, const_cast
http://www.cnblogs.com/chio/archive/2007/07/18/822389.html 首先回顾一下C++类型转换: C++类型转换分为:隐式类型转换和显式类型转换 第1 ...
- 数据库优化和SQL操作的相关题目
SQL操作 1.有一个数据库表peope,表有字段name,age,address三个属性(注:没有主键).现在如果表中有重复的数据,请删去重复只留下其中的一条.重复的定义就是两条记录的name,ag ...
- Vim折叠模式设置
参考文章:http://www.cnblogs.com/welkinwalker/archive/2011/05/30/2063587.html set foldmethod=indent " ...
- [原]网站跨站点脚本,Sql注入等攻击的处理
从360安全论坛里找到的一段代码,经过整理封装,直接在站点Global.asax文件或写一个HttpModule来拦截恶意请求即可: http://bbs.webscan.360.cn/forum.p ...
- ThinkPHP的增、删、改、查
一.创建操作 在ThinkPHP使用add方法新增数据到数据库. 使用方法如下: $User = M()->; $data[););')->delete();
- hdu 4280 最大流sap
模板套起来 1 5 7 //5个结点,7个边 3 3 //坐标 3 0 3 1 0 0 4 5 1 3 3 //相连的结点和流 2 3 4 2 4 3 1 5 6 4 5 3 1 4 4 3 4 2 ...
- 为什么是List list = new ArrayList() 而不直接用ArrayList
为什么是List list = new ArrayList(),而不直接用ArrayList? 编程是要面向对象编程,针对抽象(接口),而非具体.List 是接口,ArrayList是实现. 实现Li ...
- ERStudio的使用
转自于:http://www.cnblogs.com/TangPro/p/3250320.html 打开ERstudio,点击新建出现如图对话框: 选择第一个,表示创建一个新的关系型 数据库模型 这里 ...
- andorid开发易范的错误
1 写DAO,调用远程API接口返回不来数据,实际这个api接口经过第三方工具测试通过的,原因是没有放到线程里.