[Swust OJ 1126]--神奇的矩阵(BFS,预处理,打表)
2015-06-14 20:58
387 查看
题目链接:http://acm.swust.edu.cn/problem/1126/
Time limit(ms): 1000 Memory limit(kb): 65535
上一周里,患有XX症的哈特13成功解决了填数矩阵问题。
不知道他这一周又从哪儿弄来一神奇的矩阵,于是逃课潜心研究了一周,终于发现了其中的奥秘:
该矩阵有2行、4列,即8个小方块,每个小方块上有一个数字,即:
1 2 3 4
5 6 7 8
对于这个神奇的矩阵,有3种变换方式,具体如下:
变换A:上下两行数字互换,如上图可变为:
5 6 7 8
1 2 3 4
变换B:每行同时向右循环移动一格,如上图可变为:
4 1 2 3
8 5 6 7
变换C:中间4个方块顺时针旋转90度,如上图可变为:
1 6 2 4
5 7 3 8
哈特13虽然发现了这些变换规则,但是他并不知道怎么解决如下问题:
现在给出一个初始状态和目标状态,怎么变换才能使得矩阵从初始状态变为目标状态且变换步数最少。如果有多种变换方案,输出变换序号字典序最小的那种方案。
请你帮助他。
Description
多组输入,约1000组,直到文件末尾。
每组数据包括4行,前两行为初始状态,后两行为目标状态。
Input
对于每组输入,输出满足要求的变换方案。
Output
Sample Input
Sample Output
Sorry,由于OJ原因,换行请用\r\n
解题思路:直接从初始状态按照3种变换规则BFS,找到达到每个排列状态下的矩阵的最短路径(最少变换次数)找到对应状态下的一个序列值
(就相当于8个数全排列,直接找这是第几个排列),然后在string 数组中把每个状态的答案存贮了,到时候直接按照状态查找就是
值得注意的是每个状态下对应的记录数组的下标怎么找(这里有代码和详解:http://www.cnblogs.com/zyxStar/p/4563936.html)
注意:这里有一个坑点,那就是给出的初始序列不一定是12345678,我们需要将其对应过来(wa了n次),具体的看代码吧~~~
View Code
Time limit(ms): 1000 Memory limit(kb): 65535
上一周里,患有XX症的哈特13成功解决了填数矩阵问题。
不知道他这一周又从哪儿弄来一神奇的矩阵,于是逃课潜心研究了一周,终于发现了其中的奥秘:
该矩阵有2行、4列,即8个小方块,每个小方块上有一个数字,即:
1 2 3 4
5 6 7 8
对于这个神奇的矩阵,有3种变换方式,具体如下:
变换A:上下两行数字互换,如上图可变为:
5 6 7 8
1 2 3 4
变换B:每行同时向右循环移动一格,如上图可变为:
4 1 2 3
8 5 6 7
变换C:中间4个方块顺时针旋转90度,如上图可变为:
1 6 2 4
5 7 3 8
哈特13虽然发现了这些变换规则,但是他并不知道怎么解决如下问题:
现在给出一个初始状态和目标状态,怎么变换才能使得矩阵从初始状态变为目标状态且变换步数最少。如果有多种变换方案,输出变换序号字典序最小的那种方案。
请你帮助他。
Description
多组输入,约1000组,直到文件末尾。
每组数据包括4行,前两行为初始状态,后两行为目标状态。
Input
对于每组输入,输出满足要求的变换方案。
Output
1234 5678 5738 1624 |
CA |
Sorry,由于OJ原因,换行请用\r\n
解题思路:直接从初始状态按照3种变换规则BFS,找到达到每个排列状态下的矩阵的最短路径(最少变换次数)找到对应状态下的一个序列值
(就相当于8个数全排列,直接找这是第几个排列),然后在string 数组中把每个状态的答案存贮了,到时候直接按照状态查找就是
值得注意的是每个状态下对应的记录数组的下标怎么找(这里有代码和详解:http://www.cnblogs.com/zyxStar/p/4563936.html)
注意:这里有一个坑点,那就是给出的初始序列不一定是12345678,我们需要将其对应过来(wa了n次),具体的看代码吧~~~
#include<iostream> #include<cstring> #include<string> #include<map> #include<queue> using namespace std; typedef struct{ string path, mpt; }node; int vis[326888]; int cur[] = { 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 326880 }; //依次为1的阶乘,2的阶乘。。。。。8各数在一个数位置确定时剩余 7! 种排列情况,以此类推 string opera[326888]; /****************************************** 寻找对应状态下对应数字编号!!!! 查找 "当前数" 确定情况下剩下的 "排列" C(n 1)*(n-i)! 当前数状确定态下的排列种数, 依次递推到最后一位叠加, 每一个状态有且只有一个数对应 *********************************************/ int get_num(string x){ int i, j, a, b, cnt = 0, book[9]; memset(book, 0, sizeof(book)); for (i = 0; i < 8; i++){ a = x[i] - '0', b = 0; for (j = 1; j < a; j++){ if (!book[j]) b++; } cnt += b*cur[8 - i]; book[a] = 1; } return cnt + 1; } void bfs(){ queue<node>Q; node now, next; now.mpt = "12345678", now.path = ""; Q.push(now); vis[get_num(now.mpt)] = 1; while (!Q.empty()){ now = Q.front(); Q.pop(); opera[get_num(now.mpt)] = now.path; for (int i = 0; i < 3; i++){ next = now; if (!i){ next.path += 'A'; swap(next.mpt[0], next.mpt[4]); swap(next.mpt[1], next.mpt[5]); swap(next.mpt[2], next.mpt[6]); swap(next.mpt[3], next.mpt[7]); } else if (i == 1){ next.path += 'B'; char s1 = next.mpt[3]; for (int j = 3; j > 0; j--) next.mpt[j] = next.mpt[j - 1]; next.mpt[0] = s1; char s2 = next.mpt[7]; for (int j = 7; j > 3; j--) next.mpt[j] = next.mpt[j - 1]; next.mpt[4] = s2; } else{ next.path += 'C'; swap(next.mpt[5], next.mpt[1]); swap(next.mpt[5], next.mpt[6]); swap(next.mpt[2], next.mpt[6]); } if (!vis[get_num(next.mpt)]){ vis[get_num(next.mpt)] = 1; Q.push(next); } } } } int main(){ bfs(); string x1, x2, y1, y2; while (cin >> x1 >> x2 >> y1 >> y2){ x1 += x2, y1 += y2; pair<char, char>change[10]; for (int i = 1; i <= 8; i++){ change[i].first = x1[i - 1]; change[i].second = i + '0'; } for (int i = 1; i <= 8; i++) for (int j = 1; j <= 8; j++){ if (y1[i - 1] == change[j].first){ y1[i - 1] = change[j].second; break; } } cout << opera[get_num(y1)] << "\r\n"; //cout << y1; } return 0; }
View Code
相关文章推荐
- Windows7系统电脑出现蓝屏该怎么处理?
- UI design
- Mysql error 1217
- HDU3605Escape(最大流SAP+状态压缩优化点的个数)
- Cocos2dx基础使用相关面试题
- 谷歌是如何get到设计这个技能的?
- winsows下面firefly服务器搭建
- SQLite数据库增删改查操作
- linux程序设计——内存管理(第七章)
- C++中的临时对象
- 《浪潮之巅》读书笔记3
- vim秒变成source insight,内附安装脚本和资源链接
- java下的串口通信-RXTX
- LVS+Keepalived负载均衡集群之DR模式
- 使用Cocos Studio创建一个简单的工程
- css学习笔记-1
- 第十五周 项目二:二进制文件浏览器
- Eclipse 打开时“发现了以元素'd:skin'”开头的无效内容。此处不应含有子元素
- leetcode--Populating Next Right Pointers in Each Node
- Windows Phone 8.1中圆形图片或头像的制作、优化以及Stretch的四个属性值的区别