UVA

/*
  法一:
  设所给的两个面为a、b,将b固定,对a进行颠倒、旋转的有关处理,如下:
  对a,循环考虑6种情况,分别是6个面作为上面的情况
  在这6种情况中,每种都要进行3次旋转,也就是考虑4种情况(固定上下面的情况下,其他4个面,都要作为正面1次)
  
  思路来自blog:
  http://blog.csdn.net/qq_18738333/article/details/44968341
*/
#include <iostream>
#include <cstring>
using namespace std;
const int N = 20;
char a[N], b[N], s[N];
int dir[6][6] = { { 0, 1, 2, 3, 4, 5 }, { 1, 5, 2, 3, 0, 4 }, { 2, 1, 5, 0, 4, 3 }, { 3, 1, 0, 5, 4, 2 }, { 4, 5, 3, 2, 0, 1 }, { 5, 1, 3, 2, 4, 0 } };

bool judge()
{
	char tp[10]; // temp;
	for (int i = 0; i < 6; i++)
	{
		for (int j = 0; j < 6; j++)
		tp[j] = a[dir[i][j]]; // 将骰子的状态,置为编号所代表的面为正方体上面
		tp[6] = 0;
		
		for (int i = 0; i < 4; i++) //除去上面和下面以外,剩下的4个面,轮流做前面
		{
			char ch = tp[1];
			tp[1] = tp[2];
			tp[2] = tp[4];
			tp[4] = tp[3];
			tp[3] = ch;
			
			if (!strcmp(tp, b)) return true;
		} 
	}
	return false;
}

int main()
{
	while (cin >> s)
	{
		for (int i = 0; i < 6; i++) a[i] = s[i];
		for (int i = 0; i < 6; i++) b[i] = s[6 + i];
		a[6] = b[6] = 0;
		
		if (judge()) cout << "TRUE" << endl;
		else cout << "FALSE" << endl;
	}
	return 0;
}





/*
  法二:
  法二真是看问题直抓本质的一种方法,初次搜索后看到时,简直觉得惊为天人啊!(此处成语好像运用不得当,不要在意这些细节,反正就是十分惊叹...)
  
  总结一下法二,法二就是,根本不旋转、颠倒,而是找规律:何时两个正方形等价?
  它们的6个面,可以组成3组相对的面,只要判断2个正方形的3个对立面是否一致即可
  
  思路来自blog:
  http://blog.csdn.net/qq_20480611/article/details/48899907
*/

#include <iostream>
using namespace std;
const int N = 12;
char a[N], b[N], s[N];

int main()
{
	while (cin >> s)
	{
		int flag;
		for (int i = 0; i < 6; i++) a[i] = s[i];
		for (int i = 0; i < 6; i++) b[i] = s[i + 6];
		
		int i;
		for (i = 0; i < 3; i++)
		{
			flag = 0;
			for (int j = 0; j < 6; j++)
			{
				if (a[i] == b[j] && a[5 - i] == b[5 - j])
				//每次检查到b的一对和a相同的正对面,必须将b中这两个位置清零,避免这对面再后面的循环中,再次被用到,使得多对一的错误情况仍被程序判对
				{
					flag = 1;
					b[j] = b[5 - j] = 0;
					break;
				} 
			}
			
			if (!flag) //如果没能在b中找到a中存在的一对面的颜色组合,则肯定是不同的正方体 
			break;
		}
		if (flag) cout << "TRUE" << endl;
		else cout << "FALSE" << endl;
	}
	return 0;
}

/*
  法三:
  和法二有相似之处,都是用统计对面颜色组合的思想
  不同的是,法三不像法二一样用循环枚举,而是直接保存在二维数组中,在检查对应数据是否一致
  
  对于顺序,法三的处理方法是:对于每组对面,两种颜色先按原来的顺序累加一次,再交换顺序,再累加一次,这样就完全排除了顺序的影响
*/

#include <iostream>
#include <cstring> 
using namespace std;
const int N = 130;
const int M = 20;
char a[N], b[N];
char s[M];
int cube1[N][N], cube2[N][N]; 

int main()
{
	while (cin >> s)
	{
		memset(cube1, 0, sizeof (cube1));
		memset(cube2, 0, sizeof (cube2));
		
		for (int i = 0; i < 6; i++) a[i] = s[i]; a[6] = 0;
		for (int i = 0; i < 6; i++) b[i] = s[i + 6]; b[6] = 0;
 		
		for (int i = 0; i < 3; i++)
		{
			cube1[a[i]][a[5 - i]]++;
			cube1[a[5 - i]][a[i]]++;
			cube2[b[i]][b[5 - i]]++;
			cube2[b[5 - i]][b[i]]++;
		}
		
		int i;
		for (i = 0; i < 3; i++)
		if (cube1[s[i]][s[5 - i]] != cube2[s[i]][s[5 - i]])
		break;
		
		if (i == 3) cout << "TRUE" << endl;
		else cout << "FALSE" << endl;
	}
	return 0;
}


/*
  法四:
  和法二法三的本质类似,是我当时看到那种思路时,就想到,可以把一对面的颜色作为一对pair,定义两个元素个数为3的pair数组,先通过初始化(将pair中较大的元素换为first)数组,消除位置的影响,再对pair排序,如果排序后,两个pair数组里,面的组合完全一致,说明是同样的正方体
*/

#include <iostream>
#include <algorithm>
using namespace std;
typedef pair<int, int> p;
const int N = 12;
char a[N], b[N], s[N];
p facea[3], faceb[3];

void solve()
{
	for (int i = 0; i < 3; i++) //排序前作处理,使得面的颜色组合和顺序无关 
	{
		if (facea[i].first < facea[i].second) swap(facea[i].first , facea[i].second);
		if (faceb[i].first < faceb[i].second) swap(faceb[i].first , faceb[i].second);
	}
	sort(facea, facea + 3); sort(faceb, faceb + 3);
	for (int i = 0; i < 3; i++)
	if (facea[i] != faceb[i])
	{
		cout << "FALSE" << endl;
		return;
	}
	cout << "TRUE" << endl;
}

int main()
{
	while (cin >> s)
	{
		for (int i = 0; i < 6; i++) a[i] = s[i];
		for (int i = 0; i < 6; i++) b[i] = s[i + 6];
		
		for (int i = 0; i < 3; i++)
		{
			facea[i].first = a[i]; facea[i].second = a[5 - i];
			faceb[i].first = b[i]; faceb[i].second = b[5 - i];
		}
		
		solve();
	}
	return 0;
}




原文地址:https://www.cnblogs.com/mofushaohua/p/7789494.html