习题4-4 uva253骰子涂色

  1. 想了好一阵子才想出一个自认为较简洁的方法,一开始总想着是不是跟排序有关系,经过怎么想也想不出来有什么关系之后发现也只能是模拟骰(tóu)子转动进行穷举。
  2. 题目要求:按照  上、前、左、右、后、下  的顺序给定两个骰子的颜色,判断两个骰子是否等价。
  3. 我不喜欢题目给定的这个顺序,没规律,变换时不好写,但是既然都给定了顺序,就凑活凑活吧。
  4. 解题思路:把上、前、左、右、后、下编号0 1 2 3 4 5,要知道一个骰子(假设6个面都不一样,比如普通骰子)共有24种摆放方式,以普通骰子为例,点数1朝上的情况下有4种,然后点数2朝上......共24种。让6个面都朝上一次,每次中再加一个循环逆时针或顺时针旋转,检验两个骰子是否一样。
  5. 采用记录数组下标的方式记录变换。例如:设骰子A= {a, b, c, d, e, f}(a-f仅表示某种颜色),那么 "103254" 表示对A进行变换,变换后记作AA = {A[1], A[0], A[3], A[2], A[5], A[4]} = {b, a, d, c, f, e},这样原先a朝上的骰子变为了b朝上,各个面之间相对位置没有改变。其他变换在纸上画一画就能很容易得到。

AC代码如下

#include <bits/stdc++.h>
using namespace std;
char a[15], b[6]; //数组b存储第一个骰子初始状态
int c[] = {0, 2, 4, 1, 3, 5};//水平逆时针旋转所需要的变换
char init[6][7] = {"012345", "103254", "240513", "425031", "351402", "534120"};//6个面分别朝上所需要变换,需要使用数组b,太长所以用字符串表示
bool same() {
    for(int i = 0; i < 6; i++)
        if(a[i] != a[i + 6])
            return false;
    return true;
}
void change() {
    char temp[6];
    for(int i = 0; i < 6; i++)
        temp[i] = a[c[i]];
    strncpy(a, temp, 6);
}
int main() {
    while(cin >> a) {
        strncpy(b, a, 6);
        bool res = false;
        for(int i = 0; i < 6 && !res; i++) {
            for(int k = 0; k < 6; k++)
                a[k] = b[init[i][k] - '0'];
            for(int j = 0; j < 4; j++) {
                if(same()) {
                    res = true;
                    break;
                }
                change();
            }
        }
        cout << (res ? "TRUE\n" : "FALSE\n");
    }
    return 0;
}

2月24日更新:

也可以直接把24种情况的面顺序写出来,然后比较,只要有一种情况相等就是涂色相同。代码更短

代码如下:

#include <iostream>
using namespace std;
const char* state[]  = {"012345", "024135", "043215", "031425", "103254", "120534", "152304", "135024", "201453", "215043", "254103", "240513",
                        "304152", "310542", "351402", "345012", "402351", "425031", "430521", "453201", "513240", "521430", "542310", "534120"};
char color[13];
bool issame(int icase) {
    for(int i = 0; i < 6; i++)
        if(color[state[icase][i]-'0'] != color[i + 6])
            return false;
    return true;
}
int main() {
    while(cin >> color) {
        bool res = false;
        for(int i = 0; i < 24; i++)
            if(res = issame(i))//如果res为假,继续循环,不影响,为真则直接跳出
                break;
        cout << (res ? "TRUE\n" : "FALSE\n");
    }
    return 0;
}

测试提交,可以AC
 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值