这是属于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();
}
}