[sicily]1151. 魔板[Special judge]

来源:互联网 发布:中级软件开发工程师 编辑:程序博客网 时间:2024/06/10 02:41
Description

题目和A题相同,在这里我们把数据范围扩大:N可能超过10

请仔细考虑各种情况。
Input

输入包括多个要求解的魔板,每个魔板用三行描述。

第一行步数N,表示最多容许的步数。

第二、第三行表示目标状态,按照魔板的形状,颜色用18的表示。

当N等于-1的时候,表示输入结束。
Output

对于每一个要求解的魔板,输出一行。

首先是一个整数M,表示你找到解答所需要的步数。接着若干个空格之后,从第一步开始按顺序给出M步操作(每一步是ABC),相邻两个操作之间没有任何空格。

注意:如果不能达到,则M输出-1即可。
Sample Input
 Copy sample input to clipboard
45 8 7 64 1 2 338 7 6 51 2 3 4-1
Sample Output
2  AB1  A评分:M超过N或者给出的操作不正确均不能得分。

Problem Source: ZSUACM Team Member


#include <iostream>#include <stdio.h>#include <vector>#include <algorithm>#include <queue>#include <map>using namespace std;class MagicPad{public:vector<char> changeHistory;int magicPad[2][4];MagicPad(){magicPad[0][0] = 1;magicPad[0][1] = 2;magicPad[0][2] = 3;magicPad[0][3] = 4;magicPad[1][0] = 8;magicPad[1][1] = 7;magicPad[1][2] = 6;magicPad[1][3] = 5;}//上下行互换void opA(){int temp[4];for(int i = 0; i < 4; i++){temp[i] = magicPad[0][i];magicPad[0][i] = magicPad[1][i];magicPad[1][i] = temp[i];}changeHistory.push_back('A');}//每次以行循环右移一个void opB(){int temp[4];int i;for(i = 0; i < 4; i++)temp[i] = magicPad[0][i];for(i = 1; i < 4; i++)magicPad[0][i] = temp[i-1];magicPad[0][0] = temp[3];for(i = 0; i < 4; i++)temp[i] = magicPad[1][i];for(i = 1; i < 4; i++)magicPad[1][i] = temp[i-1];magicPad[1][0] = temp[3];changeHistory.push_back('B');}//中间四小块顺时针转一格void opC(){int temp = magicPad[0][1];magicPad[0][1] = magicPad[1][1];magicPad[1][1] = magicPad[1][2];magicPad[1][2] = magicPad[0][2];magicPad[0][2] = temp;changeHistory.push_back('C');}bool checkEqual(int finalState[][4]){for (int i = 0; i < 2; i++)for (int j = 0; j < 4; j++)if (magicPad[i][j] != finalState[i][j])return false;return true;}int getIndex(){return 10000 * (magicPad[0][0] * 1000 + magicPad[0][1] * 100 + magicPad[0][2] * 10 + magicPad[0][3]) + (magicPad[1][0] * 1000 + magicPad[1][1] * 100 + magicPad[1][2] * 10 + magicPad[1][3]);}};int finalState[2][4];int main(){int maxStep;while(scanf("%d", &maxStep), maxStep!=-1){for(int i = 0; i < 2; i++)for(int j = 0; j < 4; j++)scanf("%d", &finalState[i][j]);queue<MagicPad> state;state.push(MagicPad());map<int, bool> isVisit;bool succeed = false;while(!state.empty()){MagicPad current = state.front();if (current.changeHistory.size() > maxStep)state.pop();else if (current.checkEqual(finalState)){succeed = true;printf("%d ", current.changeHistory.size());for (int i = 0; i < current.changeHistory.size(); i++)printf("%c", current.changeHistory[i]);printf("\n");break;}else{state.pop();MagicPad next = current;next.opA();int index = next.getIndex();if (!isVisit[index]){state.push(next);isVisit[index] = true;}next = current;next.opB();index = next.getIndex();if (!isVisit[index]){state.push(next);isVisit[index] = true;}next = current;next.opC();index = next.getIndex();if (!isVisit[index]){state.push(next);isVisit[index] = true;}}}if (!succeed)printf("-1\n");}return 0;}

感想:

一开始直接BFS, 直接超时了。

后来加入是否visited过的判断,由于用的是数组保存isVIsited难以判断大小,开得太大超内存,太小runTImeError

最后用map<int, bool>代替数组顺利通过

所以,当难以判断数组大小的时候,尽量用map来代替

0 0
原创粉丝点击