/*
相对于1150,这一题需要在细节上节省更多时间,包括以下几点:
1、string的处理效率太低,此处使用int数组存储数据,
也可以直接使用int,但在进行ABC转换时就需要进行乘除法,
会浪费很多时间,相对来说对数组的操作更快
而且重点在于,使用数组时对ABC操作的修改更为方便
2、使用康拓展开进行哈希操作,构建哈希表进行快速查询
*/
/*
Run Time: 0.21secs
Run Memory: 940KB
*/
#include <iostream>
#include <string>
#include <memory.h> //memset初始化
#include <set>
#include <queue>
using namespace std;
typedef struct Node{
int node[8];
string parents;
};
int N; //要求步数
int dest[8]; //目标状态
int source[] = {1, 2, 3, 4, 8, 7, 6, 5}; //初始状态
int cantorNum[] = {5040, 720, 120, 24, 6, 2, 1, 1}; //长为n的序列的康拓展开需要用到的数:7!,6!...1!,0!
int cantor(const Node& theNode){
int result = 0;
for(int i=0; i<8; i++){
int num = 0;
for(int j=i+1; j<8; j++){
if(theNode.node[j] < theNode.node[i]){
num++;
}
}
result += num * cantorNum[i];
}
return result;
}
bool isSame(int a[8], int b[8]){
for(int i=0; i<8; i++)
if(a[i] != b[i])
return false;
return true;
}
//A:上下行互换
Node A(const Node& inputNode){
Node newOne;
newOne.node[0] = inputNode.node[4];
newOne.node[1] = inputNode.node[5];
newOne.node[2] = inputNode.node[6];
newOne.node[3] = inputNode.node[7];
newOne.node[4] = inputNode.node[0];
newOne.node[5] = inputNode.node[1];
newOne.node[6] = inputNode.node[2];
newOne.node[7] = inputNode.node[3];
newOne.parents = inputNode.parents + "A";
return newOne;
}
//B:每次以行循环右移一个
Node B(const Node& inputNode){
Node newOne;
newOne.node[0] = inputNode.node[3];
newOne.node[1] = inputNode.node[0];
newOne.node[2] = inputNode.node[1];
newOne.node[3] = inputNode.node[2];
newOne.node[4] = inputNode.node[7];
newOne.node[5] = inputNode.node[4];
newOne.node[6] = inputNode.node[5];
newOne.node[7] = inputNode.node[6];
newOne.parents = inputNode.parents + "B";
return newOne;
}
//C:中间四小块顺时针转一格
Node C(const Node& inputNode){
Node newOne;
newOne.node[0] = inputNode.node[0];
newOne.node[1] = inputNode.node[5];
newOne.node[2] = inputNode.node[1];
newOne.node[3] = inputNode.node[3];
newOne.node[4] = inputNode.node[4];
newOne.node[5] = inputNode.node[6];
newOne.node[6] = inputNode.node[2];
newOne.node[7] = inputNode.node[7];
newOne.parents = inputNode.parents + "C";
return newOne;
}
Node find(Node sourceNode){
queue<Node> nodeQueue; //节点队列
int used[50000]; //使用过的状态
memset(used, 0, sizeof(used));
if(isSame(sourceNode.node, dest))
return sourceNode;
nodeQueue.push(sourceNode);
used[cantor(sourceNode)] = 1;
while(!nodeQueue.empty()){
Node theNode = nodeQueue.front(); //获取队列头
nodeQueue.pop();
if(theNode.parents.length() >= N){ //超出步数时候退出循环
break;
}
Node bufNewNode[3];
bufNewNode[0] = A(theNode);
bufNewNode[1] = B(theNode);
bufNewNode[2] = C(theNode);
for(int i=0; i<3; i++){
if(isSame(bufNewNode[i].node, dest)) //如果找到了目标,则返回结果
return bufNewNode[i];
if(used[cantor(bufNewNode[i])] == 0){ //不是目标则检查其是否已经看过,否则记录的同时放入队列
nodeQueue.push(bufNewNode[i]);
used[cantor(bufNewNode[i])] = 1;
}
}
}
Node notFound;
notFound.parents = "NotFound";
return notFound;
}
int main()
{
while (cin>>N && (N!=-1)){
for(int i=0; i<8; i++)
cin >> dest[i];
//设定初始状态,传入方法开始执行
Node bufNode;
for(int i=0; i<8; i++)
bufNode.node[i] = source[i];
bufNode.parents = "";
Node destNode = find(bufNode);
if(destNode.parents == "NotFound"){
cout << "-1" << endl;
}else{
cout << destNode.parents.length() << " " << destNode.parents << endl;
}
}
return 0;
}
Sicily 1151. 魔板[Speical judge]
最新推荐文章于 2015-10-11 14:54:29 发布