SOJ 1151. 魔板

题目大意:和soj 1150题目大意差不多,不过数据规模变大了,n可能大于10。

解题思路:在1150的基础上作修改,修改状态重复判断的方式。以前是:扫描整个队列,查重;现在是:引入set集合,每个元素只记录up和down的值,进行查重。

代码如下:

  1 #include <iostream>
  2 #include <vector>
  3 #include <string>
  4 #include <set>
  5 using namespace std;
  6
  7 class MagicPlate {
  8 public:
  9     void setUp(int u) {
 10         up = u;
 11     }
 12
 13     void setDown(int d) {
 14         down = d;
 15     }
 16
 17     bool stateEqual(const MagicPlate & mp) {
 18         return up == mp.up && down == mp.down;
 19     }
 20
 21     void reset() {
 22         up = 1234;
 23         down = 8765;
 24         op = NULL;
 25         pre = -1;
 26     }
 27
 28     void operateA() {
 29         int temp = up;
 30         up = down;
 31         down = temp;
 32
 33         op = ‘A‘;
 34     }
 35
 36     void operateB() {
 37         up = up / 10 + up % 10 * 1000;
 38         down = down / 10 + down % 10 * 1000;
 39
 40         op = ‘B‘;
 41     }
 42
 43     void operateC() {
 44         int u = up % 1000 / 10;
 45         int u1 = u / 10;
 46         int u2 = u % 10;
 47         int d = down % 1000 / 10;
 48         int d1 = d / 10;
 49         int d2 = d % 10;
 50
 51         up = up / 1000 * 1000 + d1 * 100 + u1 * 10 + up % 10;
 52         down = down / 1000 * 1000 + d2 * 100 + u2 * 10 + down % 10;
 53
 54         op = ‘C‘;
 55     }
 56
 57     void setPre(int p) {
 58         pre = p;
 59     }
 60
 61     int getPre() {
 62         return pre;
 63     }
 64
 65     char getOp() {
 66         return op;
 67     }
 68
 69     int getUp() {
 70         return up;
 71     }
 72
 73     int getDown() {
 74         return down;
 75     }
 76
 77 private:
 78     int up;
 79     int down;
 80     char op;
 81     int pre;
 82 };
 83
 84
 85
 86 vector<MagicPlate> vt;
 87 set< pair<int, int> > s;
 88 string opStr;
 89 int fp, rp;
 90 int n;
 91
 92 void init() {
 93     opStr = "";
 94     vt.clear();
 95     s.clear();
 96 }
 97
 98 void getGoal(MagicPlate * mp) {
 99     while (mp->getPre() != -1) {
100         opStr.push_back(mp->getOp());
101         mp = &vt[mp->getPre()];
102     }
103 }
104
105 bool visited(MagicPlate *mp) {
106     pair<int, int> p = pair<int, int>(mp->getUp(), mp->getDown());
107
108     if (s.find(p) != s.end()) {
109         return true;
110     } else {
111         return false;
112     }
113     //return false;
114     /*for (int i = 0; i <= fp; i++) {
115         if (vt[i].stateEqual(mp)) {
116             return true;
117         }
118     }
119     return false;*/
120 }
121
122 int main() {
123     while (cin >> n, n != -1) {
124         init();
125         int temp;
126         int up = 0;
127         for (int i = 0; i < 4; i++) {
128             cin >> temp;
129             up = up * 10 + temp;
130         }
131         int down = 0;
132         for (int i = 0; i < 4; i++) {
133             cin >> temp;
134             down = down * 10 + temp;
135         }
136         MagicPlate targetMP;
137         targetMP.setUp(up);
138         targetMP.setDown(down);
139
140         MagicPlate begin;
141         begin.reset();
142         vt.push_back(begin);
143         s.insert(pair<int, int>(begin.getUp(), begin.getDown()));
144         fp = 0;
145         rp = 1;
146
147         if (targetMP.stateEqual(begin)) {
148             cout << 0 << endl;
149             continue;
150         }
151
152         bool flag = false;
153         int step;
154         for (step = 1; step <= n; step++) {
155             int trp = rp;
156             while (fp < trp) {
157                 MagicPlate mp = vt[fp];
158                 MagicPlate mpA(mp);
159                 mpA.operateA();
160                 mpA.setPre(fp);
161                 if (mpA.stateEqual(targetMP)) {
162                     getGoal(&mpA);
163                     flag = true;
164                     break;
165                 } else if (!visited(&mpA)) {
166                     vt.push_back(mpA);
167                     s.insert(pair<int, int>(mpA.getUp(), mpA.getDown()));
168                     rp++;
169                 }
170
171                 MagicPlate mpB(mp);
172                 mpB.operateB();
173                 mpB.setPre(fp);
174                 if (mpB.stateEqual(targetMP)) {
175                     getGoal(&mpB);
176                     flag = true;
177                     break;
178                 } else if (!visited(&mpB)) {
179                     vt.push_back(mpB);
180                     s.insert(pair<int, int>(mpB.getUp(), mpB.getDown()));
181                     rp++;
182                 }
183
184                 MagicPlate mpC(mp);
185                 mpC.operateC();
186                 mpC.setPre(fp);
187                 if (mpC.stateEqual(targetMP)) {
188                     getGoal(&mpC);
189                     flag = true;
190                     break;
191                 } else if (!visited(&mpC)) {
192                     vt.push_back(mpC);
193                     s.insert(pair<int, int>(mpC.getUp(), mpC.getDown()));
194                     rp++;
195                 }
196
197                 fp++;
198             }
199             if (flag) break;
200         }
201
202         if (flag) {
203             cout << step << " " << string(opStr.rbegin(), opStr.rend()) << endl;
204         } else {
205             cout << -1 << endl;
206         }
207     }
208 }
时间: 2024-10-23 18:30:39

SOJ 1151. 魔板的相关文章

Sicily 1151. 魔板 解题报告

1151_魔板 题目链接: http://soj.me/1151 题目大意: 初始矩阵为: 1 2 3 4 8 7 6 5 有A,B,C三种操作方式来变化矩阵,给定目标矩阵,求要经过多少步能得到目标矩阵,超过步数限制误解则输出-1 思路: 为了操作简单直接用了string来存储矩阵,初始直接为"12348765",每一个状态经过三种变化可以产生三种新的状态,因此可以用宽度优先搜索来查找目标状态.因为最后还要输出变化的过程,所以对于每一个过程状态都要记录下由初始矩阵变化来的步骤.为了方便

Sicily 1151 解题报告(魔板,广搜)

      I.     原题中文大意 魔板由2*4个方块组成,用1到8的数字表示不同的块. 其初始状态是 1 2 3 4 8 7 6 5 对魔板可进行三种基本操作,这三种基本操作,可将任一种状态装换成另一种状态. A (上下行互换) B (行循环右移一格) C (中间四块顺时针转90) 8 7 6 5 1 2 3 4 4 1 2 3 5 8 7 6 1 7 2 4 8 6 3 5 II.       算法思想及解题用到的主要数据结构 广度优先搜索,已搜索过的节点不再进行记录,保证第一个找到的解

hdu1430魔板(广搜+康托展开+string应用)

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 2420    Accepted Submission(s): 511 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

hdu 魔板

#include <iostream> #include <cstring> #include <cstdio> #include <cstdlib> #include <cmath> #include <string> #include <vector> #include <list> #include <map> #include <queue> #include <stack

ACM-康托展开+预处理BFS之魔板——hdu1430

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1679    Accepted Submission(s): 354 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

Hdoj 1430 魔板 【BFS】+【康拓展开】+【预处理】

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2139    Accepted Submission(s): 452 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜

BFS [HDU 1430] 魔板

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1988    Accepted Submission(s): 407 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版——魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜色

【判重+广搜(bfs)】魔板

判重+广搜(bfs)]魔板 Time Limit: 1000MS Memory Limit: 32768KB Special Judge 有一个两行四列的魔板,每个格子里有一个1到8的数字(数字唯一),现在我们可以对魔板进行以下操作: 1.交换两行的数字. 2.将第一列移到第二列,第二列到第三列,第三列到第四列,第四列到第一列. 3.将中间四个数顺时针转一次. 现给你初始状态,我末状态请你用最小的步数将它从初始状态变到末状态. 输入: 前两行,每行4个数表示初状态. 后两行,每行4个数表示末状态

ACM-双向BFS之魔板——求助ING!

魔板 Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1675    Accepted Submission(s): 353 Problem Description 在魔方风靡全球之后不久,Rubik先生发明了它的简化版--魔板.魔板由8个同样大小的方块组成,每个方块颜色均不相同,可用数字1-8分别表示.任一时刻魔板的状态可用方块的颜