ZOJ-2477 Magic Cube

用迭代加深搜索来做,主要任务是模拟魔方的旋转,要使用旋转数组(必须细心,小心弄错)
一开始理解错题意了,只要每个面颜色都一样就可以了,而不是还原成题中给出的样子
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int xuan_c[12][12]={ //旋转侧面,三个一组
	1,4,7,13,25,37,46,49,52,45,33,21,
	7,8,9,16,28,40,48,47,46,36,24,12,
	9,6,3,19,31,43,54,51,48,39,27,15,
	3,2,1,10,22,34,52,53,54,42,30,18,
	21,20,19,18,17,16,15,14,13,12,11,10,
	37,38,39,40,41,42,43,44,45,34,35,36,
	21,33,45,52,49,46,37,25,13,7,4,1,
	12,24,36,46,47,48,40,28,16,9,8,7,
	15,27,39,48,51,54,43,31,19,3,6,9,
	18,30,42,54,53,52,34,22,10,1,2,3,
	10,11,12,13,14,15,16,17,18,19,20,21,
	36,35,34,45,44,43,42,41,40,39,38,37,
};
const int xuan_z[12][9]={ //旋转正面,两个一组
	10,11,12,24,36,35,34,22,23,
	13,14,15,27,39,38,37,25,26,
	16,17,18,30,42,41,40,28,29,
	19,20,21,33,45,44,43,31,32,
	1,2,3,6,9,8,7,4,5,
	46,47,48,51,54,53,52,49,50,
	22,34,35,36,24,12,11,10,23,
	25,37,38,39,27,15,14,13,26,
	28,40,41,42,30,18,17,16,29,
	31,43,44,45,33,21,20,19,32,
	4,7,8,9,6,3,2,1,5,
	49,52,53,54,51,48,47,46,50,
};
char str[56],a[3];
int step[6][2]; //保存步骤
void xuan(int k)
{
	char a,b,c;
	a=str[xuan_c[k][9]];
	b=str[xuan_c[k][10]];
	c=str[xuan_c[k][11]];
	for(int i=11;i>2;i--)
		str[xuan_c[k][i]]=str[xuan_c[k][i-3]];
	str[xuan_c[k][0]]=a;
	str[xuan_c[k][1]]=b;
	str[xuan_c[k][2]]=c;
	a=str[xuan_z[k][6]];
	b=str[xuan_z[k][7]];
	for(int i=7;i>1;i--)
		str[xuan_z[k][i]]=str[xuan_z[k][i-2]];
	str[xuan_z[k][0]]=a;
	str[xuan_z[k][1]]=b;
}
bool cmp() //检查是否成功
{
	for(int i=0;i<6;i++)
		for(int j=0;j<8;j++)
			if(str[xuan_z[i][j]]!=str[xuan_z[i][8]]) return false;
	return true;
}
bool dfs(int d,int md)
{
	if(cmp()) return true;
	if(d==md) return false;
	for(int i=0;i<12;i++)
	{
		xuan(i); //旋转
		step[d][0]=i%6;
		step[d][1]=(i<6?1:-1);
		if(dfs(d+1,md)) return true;
		xuan((i<6?i+6:i-6)); //还原
	}
	return false;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		for(int i=1;i<=54;i++)
			scanf(" %c",&str[i]);
		int md=0;
		while(md<=5)
		{
			if(dfs(0,md)) break;
			md++;
		}
		if(md>5) printf("-1\n");
		else
		{
			printf("%d\n",md);
			for(int i=0;i<md;i++)
				printf("%d %d\n",step[i][0],step[i][1]);
		}
	}
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值