Cube painting UVA - 253

要仔细仔细仔细看题,不然会绕到好远,理清思路的话没什么难度,应该可以有好多种方法。

对比两个给出的骰子,比较他们是不是同一个(有相同方式的上色)。输入输出很友好,没有卡人的地方。

注意要按给定的方式进行上色,题目已经默认给出了一个正方体对六个面的编号(这个编号肯定对应是当前状态的)

也就是说千万要注意,如果你认为1,6面不动的话,可以将rbgggr中的2~5位做顺延变成 gbgg然后ggbg gggb的话那就错了!

按照标号的方式 假如以1为轴向右旋转,则新的标号顺序1*~6*会变为135246这样 也就是bggg变为了ggbg。

思路是固定第二个骰子,用第一个骰子的三个对面来匹配骰子二的1-6这一对面,若成功,则对于剩下四个面来与骰子二做判定。

其实只要时固定了一个面作为顶,那么新的标号顺序就能通过初始顺序旋转求出来。一共六种,分别对应每个面当顶面。自己想一下就能想出来。

然后对于中间四个面的旋转匹配也有迹可循。同样是按照规律 共有四种状态依次循环(废话, 五次就转一圈回来了)。

接下来只要全部枚举出最多4*6种状态就可以判断这两个骰子是否相等了,上代码。

#include<iostream>
#include<string>
#define rep(i,n,t) for(int i=(n);i<(t);i++)
using namespace std;
int main()
{
    string S1, S2;
    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,0,2,3,5,1 },{ 5,4,2,3,1,0 } };
    int bod[4][4] = { { 0,1,2,3 },{ 2,0,3,1 },{ 3,2,1,0 },{ 1,3,0,2 } };
    int yu[] = { 5,4,3,2,1,0 };
    while (cin >> S1)
    {
          bool flag = false;
        //得到S1,S2
        S2 = S1.substr(6, 6);S1.erase(6); 
        //
        rep(i, 0, 6)
        {
            if (S2[0] == S1[i] && S2[5] == S1[yu[i]]) 
            {
                string head, body, tail;
                head = S1[dir[i][0]];
                rep(j, 1, 5) 
                    body += S1[dir[i][j]];
                tail = S1[dir[i][5]];
                rep(j, 0, 4) 
                {
                    string temp;
                    rep(k, 0, 4) temp+= body[bod[j][k]];
                    if (head + temp + tail == S2) flag = true;
                }
            }
            
        }
        if (flag) cout << "TRUE" << endl;
            else cout << "FALSE" << endl;
            //条件初始化
            S1.clear(); S2.clear();
    }
    return 0;
}

要注意,这个题还有另一种解法,就是对比3对 像对面,若骰子一二的三对像对面都相等,则两个骰子全等。

这个方法存在漏洞,但是也通过了ac,提醒了我们程序要鲁棒性强,不然发生这种意外情况时根本考虑不到。意识不到自己的算法竟然有错,会在错误的路上越走越远。

因为有三种颜色,ggbrrbbgbrrg用上述解法会返回true,but should be false instead of true。

附别人写的解法二代码,很简洁

#include <cstdio>
#include <cstring>

char str[15];
int vis[3];        /*每两个对面形成一组颜色对, 每个正方体有三个颜色对,
                匹配下三个颜色对是否相同。(用vis标记检查顺序)*/

int main()
{
    while(scanf("%s", str) != EOF)
    {
        int cnt = 0;
        memset(vis, 0, sizeof(vis));
        for(int i = 0; i < 3; i++)
        {
            for(int j = 0; j < 3; j++)
            {
                if((str[i] == str[6+j] && str[5-i] == str[11-j]) || (str[i] == str[11-j] && str[5-i] == str[6+j]) && !vis[j])
                {
                    vis[j] = 1;
                    cnt++;
                    break;
                }
            }
        }
        if(cnt == 3) printf("TRUE\n");
        else printf("FALSE\n");
    }
}

猜你喜欢

转载自www.cnblogs.com/worldcreator-zh/p/10562187.html