您的位置:首页 > 其它

Sicily1150 简单魔板

2014-11-04 21:11 411 查看
解题大意:

其初始状态是
1 2 3 4
8 7 6 5
对魔板可进行三种基本操作:
A操作(上下行互换):
8 7 6 5
1 2 3 4
B操作(每次以行循环右移一个):
4 1 2 3
5 8 7 6
C操作(中间四小块顺时针转一格):
1 7 2 4
8 6 3 5
用上述三种基本操作,可将任一种状态装换成另一种状态。

Input

输入包括多个要求解的魔板,每个魔板用三行描述。
第一行步数N(不超过10的整数),表示最多容许的步数。
第二、第三行表示目标状态,按照魔板的形状,颜色用1到8的表示。
当N等于-1的时候,表示输入结束。

Output

对于每一个要求解的魔板,输出一行。
首先是一个整数M,表示你找到解答所需要的步数。接着若干个空格之后,从第一步开始按顺序给出M步操作(每一步是A、B或C),相邻两个操作之间没有任何空格。
注意:如果不能达到,则M输出-1即可。
——————————————————————————————————————————————————

解题思路:因为N不大于10,所以可以用简单的DFS或BFS。这里采用DFS

数据结构:

struct node{int x, int y, char op} 记录上下两排的数字表示状态,op表示操作(A,B,C)
vector<Node> path;  记录每次遍历的操作顺序

vector<char> result;  记录最终以最小步数到达目标状态的操作顺序

注意:

因为在回溯的时候节点的状态也需要恢复操作的前一状态,所以不能只记录操作的顺序,同时要记录节点的状态,所以节点状态和操作数作为一个数据结构记录起来。
由于此题要求最小步数到达,所有在深度遍历的时候先找到最小的,先记录起来。遍历完成后再打印。其他某些情况下,找到后就可以打印,其后的不需要遍历。
代码如下:
#include<iostream>
#include<vector>
using namespace std;

struct Node{
int x;
int y;
char op;
Node(int a, int b, char op){
x=a; y=b; op=op;
}
};

Node node(1234,8765,'0');
Node target(0,0,'0');
int flag=0;
int steps=0;
int minStep = 11;
vector<Node> path;
vector<char> result;

Node doA(Node node)
{
return Node(node.y, node.x,'0');
}

Node doB(Node node)
{
return Node((node.x%10)*1000+node.x/10, (node.y%10)*1000+node.y/10,'0');
}

Node doC(Node node)
{
int i,j,a,b,i1,j1,c,d;
i = (node.x / 1000)*1000;    //x千位
j = node.x - i;
a = j / 100;      //x百位
b = (j - a * 100) / 10;  //x十位
i1 = (node.y / 1000) * 1000; //y千位
j1 = node.y - i1;
c = j1 / 100; //y百位
d = (j1 - c*100) / 10; //y十位
return Node(i+c*100+a*10+node.x%10, i1+d*100+b*10+node.y%10,'0');
}

void dfs(Node node, int n)
{
int i;

/*for(i=1;i<path.size();i++)
cout << path[i].op << " ";
cout << endl;
cout << node.x << endl << node.y << endl << endl;
system("pause");*/
//	if(flag == 1)
//		return;
if(node.x == target.x && node.y == target.y && steps < minStep){
//		flag = 1;
minStep = steps;
result.clear();
for(i=1; i<path.size(); i++)
result.push_back(path[i].op);
//cout << path[i].op;
//cout << endl;
return;
}
else if(steps >= n)
return;
else{
for(i=0; i<3; i++){
if(i==0){
steps++;
node.op = 'A';
path.push_back(node);
dfs(doA(node), n);
steps--;
path.pop_back();
}
else if(i == 1){
steps++;
node.op = 'B';
path.push_back(node);
dfs(doB(node), n);
steps--;
path.pop_back();
}
else{
steps++;
node.op='C';
path.push_back(node);
dfs(doC(node), n);
steps--;
path.pop_back();
}
}
}

}

int arrToNum(int a, int b, int c, int d)
{
return a*1000 + b*100 + c*10 + d;
}

int main()
{
int n,a,b,c,d,i;

while(cin>>n && n!= -1){
cin >> a >> b >> c >> d;
target.x = arrToNum(a,b,c,d);
cin >> a >> b >> c >> d;
target.y = arrToNum(a,b,c,d);
node.x = 1234;
node.y = 8765;
flag = 0;
steps = 0;
minStep = 11;
path.clear();
result.clear();

if(node.x == target.x && node.y == target.y)
cout << 0 << endl;
else{
path.push_back(node);
dfs(node, n);
}

if(minStep ==11)
cout << -1 << endl;
else{
cout << minStep << " ";
for(i=0; i<result.size(); i++)
cout << result[i];
cout << endl;
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: