5998 Problem D 【宽搜入门】魔板

问题 D: 【宽搜入门】魔板

时间限制: 1 Sec  内存限制: 128 MB
提交: 31  解决: 10
 

题目描述

在成功地发明了魔方之后,鲁比克先生发明了它的二维版本,称作魔板。这是一张有8个大小相同的格子的魔板: 
1 2 3 4 
8 7 6 5 
我们知道魔板的每一个方格都有一种颜色。这8种颜色用前8个正整数来表示。可以用颜色的序列来表示一种魔板状态,规定从魔板的左上角开始,沿顺时针方向依次取出整数,构成一个颜色序列。对于上图的魔板状态,我们用序列(1,2,3,4,5,6,7,8)来表示。这是基本状态。 
这里提供三种基本操作,分别用大写字母“A”,“B”,“C”来表示(可以通过这些操作改变魔板的状态): 
“A”:交换上下两行; 
“B”:将最右边的一列插入最左边; 
“C”:魔板中央四格作顺时针旋转。 
下面是对基本状态进行操作的示范: 
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 
对于每种可能的状态,这三种基本操作都可以使用。 
你要编程计算用最少的基本操作完成基本状态到目标状态的转换,输出基本操作序列。 
【输入格式】 
输入有多组测试数据 
只有一行,包括8个整数,用空格分开(这些整数在范围 1——8 之间),表示目标状态。 
【输出格式】 
Line 1: 包括一个整数,表示最短操作序列的长度。 
Line 2: 在字典序中最早出现的操作序列,用字符串表示,除最后一行外,每行输出60个字符。 

Sample Input

2 6 8 4 5 7 3 1

Sample Output

7

BCABCCB 

经验总结

emmmm,题目本身并不难,就是要注意它那三种变换方法,很绕人的,还有变换回来的方法.....和变过去的不一样
(╯-_-)╯╧╧  还有!要注意是从谁变成谁,初始状态是12345678 目标状态是输入的!千万别搞反了
(我刚开始就是搞反了,我说怎么算都不对甚至开始怀疑BFS有问题)((ノ*T_T*)ノ┴—┴

正确代码

#include <cstdio>
#include <map>
#include <queue>
#include <vector>

using namespace std;
char goal[10];
int termination;
struct node
{
	int step,num;
	vector<char> answer;
	node(int n,int s,vector<char> a)
	{
		num=n;
		step=s;
		answer=a;
	}
};
void swap(char str[],int flag,bool operate)
{
	if(flag==0)
	{
		char temp[8];
		for(int i=0;i<8;++i)
		{
			temp[i]=str[7-i];
		}
		for(int i=0;i<8;i++)
		{
			str[i]=temp[i];
		}
	}
	if(flag==1)
	{
		if(operate==true)
		{
			char temp=str[3];
			str[3]=str[2];
			str[2]=str[1];
			str[1]=str[0];
			str[0]=temp;
			temp=str[4];
			str[4]=str[5];
			str[5]=str[6];
			str[6]=str[7];
			str[7]=temp;
		}
		else
		{
			char temp=str[0];
			str[0]=str[1];
			str[1]=str[2];
			str[2]=str[3];
			str[3]=temp;
			temp=str[7];
			str[7]=str[6];
			str[6]=str[5];
			str[5]=str[4];
			str[4]=temp;
		}
	}
	if(flag==2)
	{
		if(operate==true)
		{
			char temp=str[1];
			str[1]=str[6];
			str[6]=str[5];
			str[5]=str[2];
			str[2]=temp;
		}
		else
		{
			char temp=str[1];
			str[1]=str[2];
			str[2]=str[5];
			str[5]=str[6];
			str[6]=temp;
		}
	}
}
queue<node> p;
map<int,bool> mp;
int combine(int num)
{
    char temp[10];
    int temp1;
    vector<char> answer;
    node s(num,0,answer);
    p.push(s);
    mp[num]=true;
    while(!p.empty())
    {
    	s=p.front();
    	p.pop();
    	sprintf(temp,"%d",s.num);
    	if(s.num==termination)
		{
			printf("%d\n",s.step);
			for(int i=0;i<s.step;++i)
			{
				if(i%60==0&&i!=0)
				{
					printf("%c\n",s.answer[i]);
				}
				else
				{
					printf("%c",s.answer[i]);
				}
			}
			return 0;
		}
    	for(int i=0;i<3;i++)
    	{
			swap(temp,i,true);
			sscanf(temp,"%d",&temp1);
			if(mp.count(temp1)==0)
			{
				node r(temp1,s.step+1,s.answer);
				r.answer.push_back(i+'A');
				p.push(r);
				mp[temp1]=true;
			}
			swap(temp,i,false);
		}
	}
}

int main()
{
	int n;
    while(~scanf("%d",&n))
    {
    	termination=n;
        for(int i=0;i<7;i++)
        {
        	scanf("%d",&n);
        	termination=termination*10+n;
		}
		combine(12345678);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/a845717607/article/details/81463037
今日推荐