【算法实验三】(BFS-分支限界)【特殊的二阶魔方】

1325.特殊的二阶魔方

时限:1000ms 内存限制:10000K  总时限:3000ms

描述

魔方大家应该都玩过。现在有一个特殊的二阶魔方,它只有一面是白色,其余五个面全是黑色。玩这个魔方当然也有特殊的规则,玩家只能通过六种方式去改变它,底层向左转一格(称为DL),底层向右转一格(称为DR),右侧向上转一格(称为RU),右侧向下转一格(称为RD),内侧顺时针转一格(称为C),内侧逆时针转一格(称为CC)。现给一魔方的状态,请在最少的步骤内把魔方还原

 

输入

按照上下左右前后的顺序给出各面的具体情况,0表示白色,1表示黑色。上下、左右、前后分别是以俯视图、左视图、正视图看到的

 

输出

输出令一面全为白色的最小步数。

 

输入样例

00
00
11
11
11
11
11
11
11
11
11
11

 

输出样例

0

#include<cstdio>
#include<cstdlib>
#include<iostream>
#include<cstring>
#include<queue>
using namespace std;

struct state
{
	int depth;
	int data[6][4];
};

bool check(state s) 
{ 
	for(int i=0, k=0; i<6; ++i, k=0)
	{
		for(int j=0; j<4; ++j) k += s.data[i][j];
		if(!k) return true;
	}
	return false;
}

ostream& operator<<(ostream& o, state s)
{
	for(int i=0; i<6; ++i)
		for(int j=0; j<2; ++j) o<<s.data[i][2*j+0] << s.data[i][2*j+1]<<endl;
	return o;
}

state DL(state s)
{
	state tar;
//	memset(&tar, 511, sizeof(state));
	tar.depth = s.depth +1;
	for(int i=0;i<4;i++) tar.data[0][i]=s.data[0][i];//up
	for(int i=2;i<6;i++) for(int j=0;j<2;j++) tar.data[i][j]=s.data[i][j];//上侧面 
	
	tar.data[2][2]=s.data[4][2]; tar.data[2][3]=s.data[4][3]; //下侧面不反转情况 
	tar.data[3][2]=s.data[5][2]; tar.data[3][3]=s.data[5][3]; 
//	cout << tar << endl;
	tar.data[4][3]=s.data[3][2]; tar.data[4][2]=s.data[3][3]; //下侧面反转情况 
	tar.data[5][2]=s.data[2][3]; tar.data[5][3]=s.data[2][2];
	
	tar.data[1][1]=s.data[1][0]; tar.data[1][3]=s.data[1][1];//底面旋转情况 
	tar.data[1][2]=s.data[1][3]; tar.data[1][0]=s.data[1][2];
	
	return tar;
}

state DR(state s)
{
	state tar;
	tar.depth = s.depth +1;
	for(int i=0;i<4;i++) tar.data[0][i]=s.data[0][i];//up
	for(int i=2;i<6;i++) for(int j=0;j<2;j++) tar.data[i][j]=s.data[i][j];//上侧面 
	
	tar.data[4][2]=s.data[2][2]; tar.data[4][3]=s.data[2][3]; //下册面不反转情况 
	tar.data[5][2]=s.data[3][2]; tar.data[5][3]=s.data[3][3]; 
	
	tar.data[3][2]=s.data[4][3]; tar.data[3][3]=s.data[4][2]; //下侧面反转情况 
	tar.data[2][3]=s.data[5][2]; tar.data[2][2]=s.data[5][3];
	
	tar.data[1][0]=s.data[1][1]; tar.data[1][1]=s.data[1][3];//底面旋转情况 
	tar.data[1][3]=s.data[1][2]; tar.data[1][2]=s.data[1][0];
	return tar;
}

state RU(state s)
{
	state tar;
	tar.depth = s.depth +1;
	for(int i=0;i<4;i++) tar.data[2][i]=s.data[2][i];//left
	for(int i=0;i<2;i++) for(int j=0;j<3;j=j+2) tar.data[i][j]=s.data[i][j];//左侧面 
	for(int i=4;i<6;i++) for(int j=0;j<3;j=j+2) tar.data[i][j]=s.data[i][j];
	for(int j=1;j<4;j=j+2) tar.data[0][j]=s.data[4][j]; //右侧面不反转情况 
	for(int j=1;j<4;j=j+2) tar.data[1][j]=s.data[5][j];
	tar.data[5][1]=s.data[0][3]; tar.data[5][3]=s.data[0][1]; //右侧面反转情况 
	tar.data[4][1]=s.data[1][3]; tar.data[4][3]=s.data[1][1];
	tar.data[3][0]=s.data[3][1]; tar.data[3][2]=s.data[3][0];//右面旋转情况 
	tar.data[3][1]=s.data[3][3]; tar.data[3][3]=s.data[3][2];
	return tar;
}

state RD(state s)
{
	state tar;
	tar.depth = s.depth +1;
	for(int i=0;i<4;i++) tar.data[2][i]=s.data[2][i];//left
	for(int i=0;i<2;i++) for(int j=0;j<3;j=j+2) tar.data[i][j]=s.data[i][j];//左侧面 
	for(int i=4;i<6;i++) for(int j=0;j<3;j=j+2) tar.data[i][j]=s.data[i][j];
	for(int j=1;j<4;j=j+2) tar.data[4][j]=s.data[0][j]; //右侧面不反转情况 
	for(int j=1;j<4;j=j+2) tar.data[5][j]=s.data[1][j];
	tar.data[0][1]=s.data[5][3]; tar.data[0][3]=s.data[5][1]; //右侧面反转情况 
	tar.data[1][1]=s.data[4][3]; tar.data[1][3]=s.data[4][1];
	tar.data[3][1]=s.data[3][0]; tar.data[3][0]=s.data[3][2];//右面旋转情况 
	tar.data[3][3]=s.data[3][1]; tar.data[3][2]=s.data[3][3];
	return tar;
}

state C(state s)
{
	state tar;
	tar.depth = s.depth +1;
	for(int i=0;i<4;i++) tar.data[5][i]=s.data[5][i];//back
	for(int i=0;i<2;i++) for(int j=0;j<2;j++) tar.data[i][j]=s.data[i][j];//后侧面 
	for(int i=2;i<4;i++) for(int j=0;j<3;j+=2) tar.data[i][j]=s.data[i][j];

	tar.data[0][3]=s.data[2][1]; tar.data[0][2]=s.data[2][3]; 
	tar.data[1][2]=s.data[3][3]; tar.data[1][3]=s.data[3][1];
	
	tar.data[2][1]=s.data[1][2]; tar.data[2][3]=s.data[1][3]; 
	tar.data[3][1]=s.data[0][2]; tar.data[3][3]=s.data[0][3];
	
	tar.data[4][0]=s.data[4][2]; tar.data[4][1]=s.data[4][0];//前旋转情况 
	tar.data[4][3]=s.data[4][1]; tar.data[4][2]=s.data[4][3];
	return tar;
}

state CC(state s)
{
	state tar;
	tar.depth = s.depth +1;
	for(int i=0;i<4;i++) tar.data[5][i]=s.data[5][i];//back
	for(int i=0;i<2;i++) for(int j=0;j<2;j++) tar.data[i][j]=s.data[i][j];//后侧面 
	for(int i=2;i<4;i++) for(int j=0;j<3;j+=2) tar.data[i][j]=s.data[i][j];
	
	tar.data[2][1]=s.data[0][3]; tar.data[2][3]=s.data[0][2]; 
	tar.data[3][3]=s.data[1][2]; tar.data[3][1]=s.data[1][3];
	
	tar.data[1][2]=s.data[2][1]; tar.data[1][3]=s.data[2][3]; 
	tar.data[0][2]=s.data[3][1]; tar.data[0][3]=s.data[3][3];
	
	tar.data[4][2]=s.data[4][0]; tar.data[4][0]=s.data[4][1];//前旋转情况 
	tar.data[4][1]=s.data[4][3]; tar.data[4][3]=s.data[4][2];
	return tar;
}

state bfs(state cube)
{
	queue<state> q;
	q.push(cube);
	while(!q.empty())
	{
		state p=q.front();
		if (check(p)) break;
		q.pop();
		q.push(DL(p));
		q.push(DR(p));
		q.push(RU(p));
		q.push(RD(p));
		q.push(C(p));
		q.push(CC(p));
	}
	return q.front();
}


int main()
{
	state cube,result;
	cube.depth=0;
	char string[3];
	for(int i=0;i<6;i++)
		for(int j=0;j<2;j++)
			{
				cin>>string;
				cube.data[i][2*j]=string[0]-'0';
				cube.data[i][2*j+1]=string[1]-'0';
			}
//	cout<<endl;
//	cout<<RU(cube)<<endl;
//	return 0;
	result=bfs(cube);
	cout<<result.depth<<endl;
	return 0;
}

/*
12
34
12
34
56
78
56
78
90
89
90
89
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值