[sicily online]1151. 魔板

题目分析:

简单魔板由于N比较小,所以可以用暴力DFS,但是这个题目N比较大,所以要进行状态判断

一共有8!个状态,需要把这些状态对应到整数上去,正好是康拓展开

所以本题DFS+康拓展开

#include<iostream>  
#include <iomanip>  
#include<stdio.h>  
#include<cmath>  
#include<iomanip>  
#include<list>  
#include <map>  
#include <vector>  
#include <string>  
#include <algorithm>  
#include <sstream>  
#include <stack>  
#include<queue>  
#include<string.h>  
#include<set>  
using namespace std;  
int N;  
char initdata[2][4]={{'1','2','3','4'},{'8','7','6','5'}};  
char goal[2][4];  


typedef struct STATUS  
{  
	vector<char> oper;  
	unsigned deep;  
	char data[2][4];
}Status;  

int factory[8] = { 0, 1, 2, 6, 24, 120,720, 5040};

bool code[40321];//共有这么多个状态

int encode(char data[][4])//康托展开
{
	int sum=0;
	for(int i=0;i<8;i++)
	{
		int count=0;
		for(int j=i+1;j<8;j++)
		{
			if(data[j/4][j%4]<data[i/4][i%4])
				count++;
		}
		sum+=count*factory[8-i-1];
	}
	return sum;
}

bool equal(char data[][4])  
{  
	for(int i=0;i<2;i++)  
	{  
		for(int j=0;j<4;j++)  
		{  
			if(data[i][j]!=goal[i][j])  
				return false;  
		}  
	}  
	return true;  
}  

int main()  
{  
	while(cin>>N&&N!=-1)  
	{  
		for(int i=0;i<8;i++)  
			cin>>goal[i/4][i%4];  
		queue<Status> qu;//表示深度  
		Status st;  
		st.deep=N;  
		memcpy(st.data,initdata,sizeof(initdata));  
		memset(code,0,sizeof(code));
		code[encode(initdata)]=true;
		qu.push(st);  
		bool flag=false;  
		while(!qu.empty())  
		{  
			Status to=qu.front();  
			qu.pop();  
			if(equal(to.data))  
			{  
				cout<<to.oper.size()<<" ";  
				for(int i=0;i<to.oper.size();i++)  
					cout<<to.oper[i];  
				cout<<endl;  
				flag=true;  
				break;  
			}  
			if(to.deep<=0)  
				continue;  
			Status op;  
			op.deep=to.deep-1;  
			memcpy(op.data,to.data,sizeof(initdata));  
			for(int i=0;i<4;i++)//A操作  
				swap(op.data[0][i],op.data[1][i]);  
			op.oper=to.oper;  
			op.oper.push_back('A'); 
			int cc=encode(op.data);
			if(code[cc]==false)
			{
				qu.push(op);
				code[cc]=true;
			}


			memcpy(op.data,to.data,sizeof(initdata));  
			for(int i=0;i<2;i++)//B操作  
			{  
				char tmp=op.data[i][3];  
				for(int j=3;j>0;j--)  
				{  
					op.data[i][j]=op.data[i][j-1];  
				}  
				op.data[i][0]=tmp;  
			}  
			op.oper=to.oper;  
			op.oper.push_back('B');  
			cc=encode(op.data);
			if(code[cc]==false)
			{
				qu.push(op);
				code[cc]=true;
			}

			memcpy(op.data,to.data,sizeof(initdata));  
			char tmp=op.data[0][1];  
			op.data[0][1]=op.data[1][1];  
			op.data[1][1]=op.data[1][2];  
			op.data[1][2]=op.data[0][2];  
			op.data[0][2]=tmp;  
			op.oper=to.oper;  
			op.oper.push_back('C');  
			cc=encode(op.data);
			if(code[cc]==false)
			{
				qu.push(op);
				code[cc]=true;
			}

		}  
		if(flag==false) cout<<-1<<endl;  
	}  
}                                 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值