骰子涂色 Cube painting

这是属于UVA中的题,洛谷也有,但是PDF版的,且有图像,没办法复制,所以题目介绍就省了吧,下面是题目的链接(这句话又再次出现了,没错,我复制我上一篇的了)。

https://www.luogu.com.cn/problem/UVA253

思路介绍

  这道题其实就是一道简单的dfs类型的题目,不过需要加上一点思考和回溯的处理。这道题的dfs方式是骰子的转动方式,以x、y、z轴为中心旋转,旋转的方式一共有六种,分别是绕x轴正负方向旋转、绕y轴正负方向旋转、绕z轴正负方向旋转。但其实正负方向旋转的得出的结果总体上没区别,只不过是得出的顺序不同而已,而且这样写递归也很奇怪,我绕x轴向正方向旋转一次,又在x轴向负方向旋转一次,那不白旋转了吗,所以一共有三种。

  回溯的处理我是用map记住(标记为true)前面旋转后得到的结果,若某一次递归的值是前面得到的结果,那这个值就不必再进行下一次递归了,因为递归以后所发生的事已经发生过一次了。这里就有个问题,就是我在某次用某个值递归后,发现路走不通,回溯后,需不需要把这个值标记为false,其实是不需要的,因为你在接下来的递归中可能会再次遇到这个值时,这时你就不必再进一步递归了,以为你已经知道其之后的递归是不会找到你需要的值。而且你若标记为false则会出错(因为我就是这样卡住了),原因其实就是你接下来的操作会陷入一个被几个标记为false的值精心设置的死循环中,这样讲有些抽象,你可以在下面的代码中,去掉注释,且输入为

bbbggrrgbbgb

在调试中,你就会发现你已经陷入死循环了。

代码样例

#include<iostream>
#include<string>
#include<algorithm>
#include<map>
using namespace std;
map<string, bool> mp;
int a[3][6] = { { 0, 3, 1, 4, 2, 5 }, { 2, 1, 5, 0, 4, 3 },{1,5,2,3,0,4} };
bool check(string f,string s)
{
	if (f == s) return true;
	for (int i = 0; i < 3; i++)
	{
		string temp("000000");
		for (int j = 0; j < 6; j++) temp[a[i][j]] = f[j];
		if (mp[temp]) continue;
		else mp[temp] = true;
		if (check(temp, s)) return true;
		//else mp[temp] = false;
	}
	return false;
}
int main()
{
	string str, str1, str2,t1,t2;
	while (cin >> str)
	{
		t1 = str1 = str.substr(0, 6);
		t2 = str2 = str.substr(6, 6);
		sort(t1.begin(), t1.end());
		sort(t2.begin(), t2.end());
		if (t1 != t2)
		{
			cout << "FALSE" << endl; continue;
		}
		if (check(str1, str2)) cout << "TRUE" << endl;
		else cout << "FALSE" << endl;
		mp.clear();
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值