ZROI2020国庆 Day3#C 自然传奇 题解

题面

问题描述

小 $c$ 看了自然传奇,有感而发,然后他出了一道题。

给出两个 $2\times2\times2$ 的立方体的展开图,如下所示:

若第一个立方体可以通过以下操作变成第二个立方体,则称它们是同构的:

  • 任意翻转整个立方体
  • 沿某个中心面镜像对称
  • 交换某两种颜色

问两个立方体是否同构。

输入格式

第一行一个整数 $T$,表示数据组数。

接下来 $T$ 组数据,每组数据 $2\times8$ 行,分别描述两个立方体的展开图。具体格式参考样例。

输出格式

$T$ 行,每行输出 yesno

样例输入

2
  46
  16
543513
624421
  35
  53
  26
  12
  44
  26
165235
414122
  53
  35
  61
  36
  43
  42
163435
646511
  16
  32
  55
  22
  64
  65
321126
535513
  44
  32
  26
  41

样例输出

yes
no

时空限制

$time\leq3s,mem\leq512MB$

数据规模

共一组数据,$T=10000$。

按照正确率下取整给分。若程序发生错误则得 0 分。

题解

骗分

为什么把骗分放在第一位呢?

性价比超高。

骗分程序只需要

#include <iostream>
using namespace std;
int main(){
  int T;
  cin>>T;
  for(int i=0;i<T;++i)cout<<"yes"<<endl;
}

这样,就可以得到 50 分了。(是因为有了良心出题人)

正解

这个题一眼看上去不像是十分考察思维的题,因为:

  • 显而易见的题目意义
  • 极其少见的(或许只是见识太少)立方体操作,可能并没有什么便捷的算法进行这类操作
  • 长达 3 秒的时间限制
  • 只有一个测试点,且 $T=10000$,不算很大,平均下来每个点有 0.3ms 的判定时间

所以说呢?

直接模拟。


这道题的模拟较为复杂,要求一定的空间想象能力(或者其他能较稳定模拟这些操作的方法)。

总结一下题面,需要从以下三个维度来考虑:

  • 旋转
  • 镜像
  • 颜色改变

直接实现就可以了,切记!!不要!!中途放弃!!并且多多测试!!


我模拟的时候,大致按照这样拆分了这个立方体(可能是写多了工程的缘故吧)。

classDiagram class cube{ +face faces[6] +rotatexr() +rotateyr() +rotatezr() +mirrorx() +mirrory() +mirrorz() +remappingcolor() +equals_remapping(cube &o) +equals_rotate(cube &o) +input() +output() } class face{ +blocks[2][2] +rotater() +rotatel() +upsidedown() +leftsideright() } cube -- face

cube 中的 operator== 函数和 face 中的 operator!= 不知道如何在 mermaid 中正确显示,在此没有列出。

并且初步做了以下规定:

展开图与立方体之间按照此关系对应。展开图中每一面左上角为 blocks[0][0]

套入 $x,y,z$ 轴时按此方式放置。

那么为什么要这样拆分呢?首先我们从输入的数据出发,输入的是六个面的颜色信息,而旋转、镜像这些操作都与立方体的面有非常大的关联,因此我们先将整个立方体拆成六个面,再针对某个面来存储它的颜色信息。

对于每个 struct 中的函数,则是完全按照其需要我们考虑的维度来设计的。在这里,我们依然从面入手考虑,这样可以使我们的程序更加模块化,虽然可能写的代码量会大一些,但是对于我这种思维不一定时刻严密的人来说,可以更方便地调试错误。

各个函数的用途应该通过名字就能很容易知道了,但还是再写一下吧0.0

cube.rotatexr()cube 绕 $x$ 轴顺时针旋转 $90^{\circ}$

cube.rotateyr()cube 绕 $y$ 轴顺时针旋转 $90^{\circ}$

cube.rotatezr()cube 绕 $z$ 轴顺时针旋转 $90^{\circ}$

cube.mirrorx()cube 沿 $x$ 轴的中心面镜像翻转

cube.mirrory()cube 沿 $y$ 轴的中心面镜像翻转

cube.mirrorz()cube 沿 $z$ 轴的中心面镜像翻转

cube.remappingcolor()cube 按照一定顺序对出现的颜色进行重映射

cube.equals_remapping(cube2) 判断 cubecube2 在重映射颜色后是否相同

cube.equals_rotate(cube2) 判断 cubecube2 在旋转、重映射颜色后是否相同

cube == cube2 判断 cubecube2 在镜像、旋转、重映射颜色后是否相同

cube.input() 按照题目格式输入到 cube

cube.output() 按照题目格式输出 cube

face.rotater()face 顺时针旋转 $90^{\circ}$

face.rotatel()face 逆时针旋转 $90^{\circ}$

face.upsidedown()face 上下颠倒

face.leftsideright()face 左右颠倒

face != face2 判断 faceface2 是否不相等

因此,我们只需要逐个实现就可以了,每个函数的思维含量都会急剧下降,让你在时间充裕的前提下非常稳妥地搞完整道题。

参考代码-便于理解版

不要惊恐,这只是因为变量名比较冗长(但是应该会更直观一点吧,也和上面的相对应)才显得很复杂。可以跳转到下一个只精简了变量、函数名称的版本

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct face{
    int blocks[2][2];
    inline void rotater(){
        int t;
        t=blocks[0][0];
        blocks[0][0]=blocks[1][0];
        blocks[1][0]=blocks[1][1];
        blocks[1][1]=blocks[0][1];
        blocks[0][1]=t;
    }
    inline void rotatel(){
        int t;
        t=blocks[0][0];
        blocks[0][0]=blocks[0][1];
        blocks[0][1]=blocks[1][1];
        blocks[1][1]=blocks[1][0];
        blocks[1][0]=t;
    }
    inline void upsidedown(){
        int t1=blocks[0][0],t2=blocks[0][1];
        blocks[0][0]=blocks[1][0];
        blocks[0][1]=blocks[1][1];
        blocks[1][0]=t1;
        blocks[1][1]=t2;
    }
    inline void leftsideright(){
        int t1=blocks[0][0],t2=blocks[1][0];
        blocks[0][0]=blocks[0][1];
        blocks[1][0]=blocks[1][1];
        blocks[0][1]=t1;
        blocks[1][1]=t2;
    }
    bool operator != (const face &o) const {
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                if(blocks[i][j]!=o.blocks[i][j])
                return true;
            }
        }
        return false;
    }
};
struct cube{
    const int front=0,left=1,top=2,right=3,bottom=4,back=5;
    face faces[6];
    inline void rotatexr(){
        faces[front].rotater();
        faces[back].rotatel();
        face t;
        t=faces[left];
        faces[left]=faces[bottom];
        faces[bottom]=faces[right];
        faces[right]=faces[top];
        faces[top]=t;
        for(int i=left;i<=bottom;i++){
            faces[i].rotater();
        }
    }
    inline void rotateyr(){
        faces[left].rotater();
        faces[right].rotatel();
        face t;
        t=faces[top];
        faces[top]=faces[back];
        faces[back]=faces[bottom];
        faces[bottom]=faces[front];
        faces[front]=t;
    }
    inline void rotatezr(){
        faces[bottom].rotater();
        faces[top].rotatel();
        face t;
        t=faces[front];
        faces[front]=faces[left];
        faces[left]=faces[back];
        faces[back]=faces[right];
        faces[right]=t;
        faces[back].upsidedown();
        faces[back].leftsideright();
        faces[left].upsidedown();
        faces[left].leftsideright();
    }
    inline void remappingcolor(cube *o) {
        int mapping[7]={-1,-1,-1,-1,-1,-1,-1},now=-1;
        for(int i=0;i<6;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    int& color = o->faces[i].blocks[j][k];
                    if(mapping[color]==-1){
                        mapping[color]=++now;
                    }
                    color = mapping[color];
                }
            }
        }
    }
    inline bool equals_remapping(cube &o) {
        remappingcolor(this);
        remappingcolor(&o);
        for(int i=0;i<6;i++){
            if(o.faces[i]!=faces[i])return false;
        }
        return true;
    }
    inline bool equals_rotate(cube o){
        for(int i=0;i<=3;i++){
            if(equals_remapping(o))return true;
            rotatexr();
            for(int j=0;j<=3;j++){
                if(equals_remapping(o))return true;
                rotateyr();
                for(int k=0;k<=3;k++){
                    if(equals_remapping(o))return true;
                    rotatezr();
                }
            }
        }
        return false;
    }
    inline void mirrorx(){
        for(int i=0;i<6;i++){
            faces[i].leftsideright();
        }
        swap(faces[left],faces[right]);
    }
    inline void mirrory(){
        faces[left].leftsideright();
        faces[right].leftsideright();
        faces[top].upsidedown();
        faces[bottom].upsidedown();
        faces[front].upsidedown();
        faces[back].upsidedown();
        swap(faces[front],faces[back]);
    }
    inline void mirrorz(){
        for(int i=0;i<6;i++){
            faces[i].upsidedown();
        }
        swap(faces[top],faces[bottom]);
    }
    inline bool operator== (cube o){
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    if(i)o.mirrorx();
                    if(j)o.mirrory();
                    if(k)o.mirrorz();
                    int res=false;
                    if(equals_rotate(o))res=true;
                    if(i)o.mirrorx();
                    if(j)o.mirrory();
                    if(k)o.mirrorz();
                    if(res)return true;
                }
            }
        }
        return false;
    }
    inline void input(){
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[top].blocks[0][0]=ch-'0';ch=getchar();
        faces[top].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[top].blocks[1][0]=ch-'0';ch=getchar();
        faces[top].blocks[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[left].blocks[0][0]=ch-'0';ch=getchar();
        faces[left].blocks[0][1]=ch-'0';ch=getchar();
        faces[front].blocks[0][0]=ch-'0';ch=getchar();
        faces[front].blocks[0][1]=ch-'0';ch=getchar();
        faces[right].blocks[0][0]=ch-'0';ch=getchar();
        faces[right].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[left].blocks[1][0]=ch-'0';ch=getchar();
        faces[left].blocks[1][1]=ch-'0';ch=getchar();
        faces[front].blocks[1][0]=ch-'0';ch=getchar();
        faces[front].blocks[1][1]=ch-'0';ch=getchar();
        faces[right].blocks[1][0]=ch-'0';ch=getchar();
        faces[right].blocks[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[bottom].blocks[0][0]=ch-'0';ch=getchar();
        faces[bottom].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[bottom].blocks[1][0]=ch-'0';ch=getchar();
        faces[bottom].blocks[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[back].blocks[0][0]=ch-'0';ch=getchar();
        faces[back].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[back].blocks[1][0]=ch-'0';ch=getchar();
        faces[back].blocks[1][1]=ch-'0';
    }
    inline void output(){
        printf("  %d%d  \n",faces[top].blocks[0][0],faces[top].blocks[0][1]);
        printf("  %d%d  \n",faces[top].blocks[1][0],faces[top].blocks[1][1]);
        printf("%d%d%d%d%d%d\n",faces[left].blocks[0][0],faces[left].blocks[0][1],faces[front].blocks[0][0],faces[front].blocks[0][1],faces[right].blocks[0][0],faces[right].blocks[0][1]);
        printf("%d%d%d%d%d%d\n",faces[left].blocks[1][0],faces[left].blocks[1][1],faces[front].blocks[1][0],faces[front].blocks[1][1],faces[right].blocks[1][0],faces[right].blocks[1][1]);
        printf("  %d%d  \n",faces[bottom].blocks[0][0],faces[bottom].blocks[0][1]);
        printf("  %d%d  \n",faces[bottom].blocks[1][0],faces[bottom].blocks[1][1]);
        printf("  %d%d  \n",faces[back].blocks[0][0],faces[back].blocks[0][1]);
        printf("  %d%d  \n",faces[back].blocks[1][0],faces[back].blocks[1][1]);
    }
};
template <typename T>
inline T read(){
    T x=0;int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int main(){
    int T;
    T=read<int>();
    while(T--){
        cube a,b;
        a.input();
        b.input();
        if(a==b){
            printf("yes\n");
        }else{
            printf("no\n");
        }
    }
    // cube a;
    // a.input();
    // a.mirrorz();
    // a.output();
    // 这一段代码是用来逐个测试以上函数功能是否正确的,当你写完以后却发现答案不正确,就可以手动进行“单元测试”
}

参考代码-变量简化版

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct face{
    int b[2][2];
    inline void rotr(){
        int t;
        t=b[0][0];
        b[0][0]=b[1][0];
        b[1][0]=b[1][1];
        b[1][1]=b[0][1];
        b[0][1]=t;
    }
    inline void rotl(){
        int t;
        t=b[0][0];
        b[0][0]=b[0][1];
        b[0][1]=b[1][1];
        b[1][1]=b[1][0];
        b[1][0]=t;
    }
    inline void swapud(){
        int t1=b[0][0],t2=b[0][1];
        b[0][0]=b[1][0];
        b[0][1]=b[1][1];
        b[1][0]=t1;
        b[1][1]=t2;
    }
    inline void swaplr(){
        int t1=b[0][0],t2=b[1][0];
        b[0][0]=b[0][1];
        b[1][0]=b[1][1];
        b[0][1]=t1;
        b[1][1]=t2;
    }
    bool operator != (const face &o) const {
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                if(b[i][j]!=o.b[i][j])
                return true;
            }
        }
        return false;
    }
};
struct cube{
    const int front=0,left=1,top=2,right=3,bottom=4,back=5;
    face f[6];
    inline void rotxr(){
        f[front].rotr();
        f[back].rotl();
        face t;
        t=f[left];
        f[left]=f[bottom];
        f[bottom]=f[right];
        f[right]=f[top];
        f[top]=t;
        for(int i=left;i<=bottom;i++){
            f[i].rotr();
        }
    }
    inline void rotyr(){
        f[left].rotr();
        f[right].rotl();
        face t;
        t=f[top];
        f[top]=f[back];
        f[back]=f[bottom];
        f[bottom]=f[front];
        f[front]=t;
    }
    inline void rotzr(){
        f[bottom].rotr();
        f[top].rotl();
        face t;
        t=f[front];
        f[front]=f[left];
        f[left]=f[back];
        f[back]=f[right];
        f[right]=t;
        f[back].swapud();
        f[back].swaplr();
        f[left].swapud();
        f[left].swaplr();
    }
    inline void remappingcolor(cube *o) {
        int mapping[7]={-1,-1,-1,-1,-1,-1,-1},now=-1;
        for(int i=0;i<6;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    int& color = o->f[i].b[j][k];
                    if(mapping[color]==-1){
                        mapping[color]=++now;
                    }
                    color = mapping[color];
                }
            }
        }
    }
    inline bool equals_remapping(cube &o) {
        remappingcolor(this);
        remappingcolor(&o);
        for(int i=0;i<6;i++){
            if(o.f[i]!=f[i])return false;
        }
        return true;
    }
    inline bool equals_rot(cube o){
        for(int i=0;i<=3;i++){
            if(equals_remapping(o))return true;
            rotxr();
            for(int j=0;j<=3;j++){
                if(equals_remapping(o))return true;
                rotyr();
                for(int k=0;k<=3;k++){
                    if(equals_remapping(o))return true;
                    rotzr();
                }
            }
        }
        return false;
    }
    inline void mirx(){
        for(int i=0;i<6;i++){
            f[i].swaplr();
        }
        swap(f[left],f[right]);
    }
    inline void miry(){
        f[left].swaplr();
        f[right].swaplr();
        f[top].swapud();
        f[bottom].swapud();
        f[front].swapud();
        f[back].swapud();
        swap(f[front],f[back]);
    }
    inline void mirz(){
        for(int i=0;i<6;i++){
            f[i].swapud();
        }
        swap(f[top],f[bottom]);
    }
    inline bool operator== (cube o){
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    if(i)o.mirx();
                    if(j)o.miry();
                    if(k)o.mirz();
                    int res=false;
                    if(equals_rot(o))res=true;
                    if(i)o.mirx();
                    if(j)o.miry();
                    if(k)o.mirz();
                    if(res)return true;
                }
            }
        }
        return false;
    }
    inline void input(){
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[top].b[0][0]=ch-'0';ch=getchar();
        f[top].b[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[top].b[1][0]=ch-'0';ch=getchar();
        f[top].b[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[left].b[0][0]=ch-'0';ch=getchar();
        f[left].b[0][1]=ch-'0';ch=getchar();
        f[front].b[0][0]=ch-'0';ch=getchar();
        f[front].b[0][1]=ch-'0';ch=getchar();
        f[right].b[0][0]=ch-'0';ch=getchar();
        f[right].b[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[left].b[1][0]=ch-'0';ch=getchar();
        f[left].b[1][1]=ch-'0';ch=getchar();
        f[front].b[1][0]=ch-'0';ch=getchar();
        f[front].b[1][1]=ch-'0';ch=getchar();
        f[right].b[1][0]=ch-'0';ch=getchar();
        f[right].b[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[bottom].b[0][0]=ch-'0';ch=getchar();
        f[bottom].b[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[bottom].b[1][0]=ch-'0';ch=getchar();
        f[bottom].b[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[back].b[0][0]=ch-'0';ch=getchar();
        f[back].b[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        f[back].b[1][0]=ch-'0';ch=getchar();
        f[back].b[1][1]=ch-'0';
    }
    inline void output(){
        printf("  %d%d  \n",f[top].b[0][0],f[top].b[0][1]);
        printf("  %d%d  \n",f[top].b[1][0],f[top].b[1][1]);
        printf("%d%d%d%d%d%d\n",f[left].b[0][0],f[left].b[0][1],f[front].b[0][0],f[front].b[0][1],f[right].b[0][0],f[right].b[0][1]);
        printf("%d%d%d%d%d%d\n",f[left].b[1][0],f[left].b[1][1],f[front].b[1][0],f[front].b[1][1],f[right].b[1][0],f[right].b[1][1]);
        printf("  %d%d  \n",f[bottom].b[0][0],f[bottom].b[0][1]);
        printf("  %d%d  \n",f[bottom].b[1][0],f[bottom].b[1][1]);
        printf("  %d%d  \n",f[back].b[0][0],f[back].b[0][1]);
        printf("  %d%d  \n",f[back].b[1][0],f[back].b[1][1]);
    }
};
template <typename T>
inline T read(){
    T x=0;int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int main(){
    int T;
    T=read<int>();
    while(T--){
        cube a,b;
        a.input();
        b.input();
        if(a==b){
            printf("yes\n");
        }else{
            printf("no\n");
        }
    }
    // cube a;
    // a.input();
    // a.mirz();
    // a.output();
    // 这一段代码是用来逐个测试以上函数功能是否正确的,当你写完以后却发现答案不正确,就可以手动进行“单元测试”
}

总结

对于这种码量较大但没什么思维含量的题,在时间充裕的情况下还是尽可能地用类似工程的方法来写代码,更多地去把大功能拆分成多个小功能再组合起来。对我这样思维不一定时刻严密的人而言,这样能够减少许多错误,并且即使出了错,也能更方便地调试出问题所在。

同时,也需要在做题之前将实际问题与代码的对应关系明确,最好是写下来,一边写一边对照,防止一不小心打岔,把参考系啥的弄混,程序全完蛋蛋了。

查错小游戏

最后的最后,再来一个查错小游戏,同样的错误,你能够很明显地发现用类似工程的方法写模拟的好处。

错误修改自 std

错误前的代码

int IN(){
	int c,f,x;
	while (!isdigit(c=getchar())&&c!='-');c=='-'?(f=1,x=0):(f=0,x=c-'0');
	while (isdigit(c=getchar())) x=(x<<1)+(x<<3)+c-'0';return !f?x:-x;
}

char s[20][20];
int A[6][4],_A[6][4],B[6][4],C[6][4];

void Input(int A[][4]){
	For(i,0,8) scanf("%s",s[i]);
	For(i,0,2){
		A[0][i]=s[2][i]-'0';
		A[0][i+2]=s[3][i]-'0';
		A[1][i]=s[0][i]-'0';
		A[1][i+2]=s[1][i]-'0';
		A[2][i]=s[2][i+2]-'0';
		A[2][i+2]=s[3][i+2]-'0';
		A[5][i]=s[2][i+4]-'0';
		A[5][i+2]=s[3][i+4]-'0';
		A[3][i]=s[4][i]-'0';
		A[3][i+2]=s[5][i]-'0';
		A[4][i]=s[6][i]-'0';
		A[4][i+2]=s[7][i]-'0';
	}
}
bool chk(){
	static int P[10];
	memset(P,-1,sizeof(P));
	For(i,0,6) For(j,0,4){
		if (P[A[i][j]]==-1) P[A[i][j]]=B[i][j];
		if (P[A[i][j]]!=B[i][j]) return 0;
	}
	return 1;
}
void work(int a,int b,int c){
	if (a){
		Rep(i,1,4){
			swap(A[i][0],A[i][1]);
			swap(A[i][2],A[i][3]);
		}
		swap(A[0][1],A[5][0]);
		swap(A[0][0],A[5][1]);
		swap(A[0][2],A[5][3]);
		swap(A[0][3],A[5][2]);
	}
	if (b){
		For(i,0,2){
			swap(A[0][i],A[0][i+2]);
			swap(A[2][i],A[2][i+2]);
			swap(A[5][i],A[5][i+2]);
			swap(A[4][i],A[4][i+2]);
		}
		swap(A[1][0],A[3][2]);
		swap(A[1][2],A[3][0]);
		swap(A[1][1],A[3][3]);
		swap(A[1][3],A[3][1]);
	}
	if (c){
		For(i,0,2){
			swap(A[1][i],A[1][i+2]);
			swap(A[3][i],A[3][i+2]);
			swap(A[0][2*i],A[0][2*i+1]);
			swap(A[5][2*i],A[5][2*i+1]);
		}
		swap(A[2][0],A[4][2]);
		swap(A[2][2],A[4][0]);
		swap(A[2][1],A[4][3]);
		swap(A[2][3],A[4][1]);
	}
}

错误代码段

void go1(){
	For(i,0,4){
		C[2][i]=A[5][i];
		C[5][i]=A[2][i];
	}
	C[4][0]=A[0][3];
	C[4][1]=A[0][2];
	C[4][2]=A[0][1];
	C[4][3]=A[0][0];
	C[0][0]=A[4][3];
	C[0][1]=A[4][2];
	C[0][2]=A[4][1];
	C[0][3]=A[4][0];
	C[1][0]=A[1][1];
	C[1][1]=A[1][3];
	C[1][2]=A[1][0];
	C[1][3]=A[1][2];
	C[3][0]=A[3][2];
	C[3][1]=A[3][0];
	C[3][2]=A[3][3];
	C[3][3]=A[3][1];
	memcpy(A,C,sizeof(C));
}
错误后的代码

void go2(){
	For(i,0,4){
		C[1][i]=A[4][i];
		C[2][i]=A[1][i];
		C[3][i]=A[2][i];
		C[4][i]=A[3][i];
	}
	C[5][0]=A[5][1];
	C[5][1]=A[5][3];
	C[5][2]=A[5][0];
	C[5][3]=A[5][2];
	C[0][0]=A[0][2];
	C[0][1]=A[0][0];
	C[0][2]=A[0][3];
	C[0][3]=A[0][1];
	memcpy(A,C,sizeof(C));
}
void go3(){
	C[4][0]=A[4][2];
	C[4][1]=A[4][0];
	C[4][2]=A[4][3];
	C[4][3]=A[4][1];
	C[3][0]=A[0][1];
	C[3][1]=A[0][3];
	C[3][2]=A[0][0];
	C[3][3]=A[0][2];
	C[5][0]=A[3][1];
	C[5][1]=A[3][3];
	C[5][2]=A[3][0];
	C[5][3]=A[3][2];
	C[1][0]=A[5][1];
	C[1][1]=A[5][3];
	C[1][2]=A[5][0];
	C[1][3]=A[5][2];
	C[0][0]=A[1][1];
	C[0][1]=A[1][3];
	C[0][2]=A[1][0];
	C[0][3]=A[1][2];
	C[2][0]=A[2][1];
	C[2][1]=A[2][3];
	C[2][2]=A[2][0];
	C[2][3]=A[2][2];
	memcpy(A,C,sizeof(C));
}
bool Main(){
	Input(A);
	Input(B);
	memcpy(_A,A,sizeof(A));
	For(a,0,2) For(b,0,2) For(c,0,2){
		memcpy(A,_A,sizeof(_A));
		work(a,b,c);
		For(x,0,4){
			For(y,0,4){
				For(z,0,4){
					go1();
					if (chk()) return 1;
				}
				go2();
			}
			go3();
		}
	}
	return 0;
}

int main(){
	freopen("natural.in","r",stdin);
	freopen("natural.out","w",stdout);
	for (int T=IN();T--;)
		if (Main()){
			puts("yes");
		} else{
			puts("no");
		}
}

错误修改自 我的代码

错误前的代码

struct face{
    int blocks[2][2];
    inline void rotater(){
        int t;
        t=blocks[0][0];
        blocks[0][0]=blocks[1][0];
        blocks[1][0]=blocks[1][1];
        blocks[1][1]=blocks[0][1];
        blocks[0][1]=t;
    }
    inline void rotatel(){
        int t;
        t=blocks[0][0];
        blocks[0][0]=blocks[0][1];
        blocks[0][1]=blocks[1][1];
        blocks[1][1]=blocks[1][0];
        blocks[1][0]=t;
    }
    inline void upsidedown(){
        int t1=blocks[0][0],t2=blocks[0][1];
        blocks[0][0]=blocks[1][0];
        blocks[0][1]=blocks[1][1];
        blocks[1][0]=t1;
        blocks[1][1]=t2;
    }
    inline void leftsideright(){
        int t1=blocks[0][0],t2=blocks[1][0];
        blocks[0][0]=blocks[0][1];
        blocks[1][0]=blocks[1][1];
        blocks[0][1]=t1;
        blocks[1][1]=t2;
    }
    bool operator != (const face &o) const {
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                if(blocks[i][j]!=o.blocks[i][j])
                return true;
            }
        }
        return false;
    }
};
struct cube{
    const int front=0,left=1,top=2,right=3,bottom=4,back=5;
    face faces[6];
    inline void rotatexr(){
        faces[front].rotater();
        faces[back].rotatel();
        face t;
        t=faces[left];
        faces[left]=faces[bottom];
        faces[bottom]=faces[right];
        faces[right]=faces[top];
        faces[top]=t;
        for(int i=left;i<=bottom;i++){
            faces[i].rotater();
        }
    }
    inline void rotateyr(){
        faces[left].rotater();
        faces[right].rotatel();
        face t;
        t=faces[top];
        faces[top]=faces[back];
        faces[back]=faces[bottom];
        faces[bottom]=faces[front];
        faces[front]=t;
    }

错误代码段

    inline void rotatezr(){
        faces[bottom].rotater();
        faces[top].rotatel();
        face t;
        t=faces[front];
        faces[front]=faces[right];
        faces[left]=faces[back];
        faces[back]=faces[left];
        faces[right]=t;
        faces[back].upsidedown();
        faces[back].leftsideright();
        faces[left].upsidedown();
        faces[left].leftsideright();
    }
错误后的代码

    inline void remappingcolor(cube *o) {
        int mapping[7]={-1,-1,-1,-1,-1,-1,-1},now=-1;
        for(int i=0;i<6;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    int& color = o->faces[i].blocks[j][k];
                    if(mapping[color]==-1){
                        mapping[color]=++now;
                    }
                    color = mapping[color];
                }
            }
        }
    }
    inline bool equals_remapping(cube &o) {
        remappingcolor(this);
        remappingcolor(&o);
        for(int i=0;i<6;i++){
            if(o.faces[i]!=faces[i])return false;
        }
        return true;
    }
    inline bool equals_rotate(cube o){
        for(int i=0;i<=3;i++){
            if(equals_remapping(o))return true;
            rotatexr();
            for(int j=0;j<=3;j++){
                if(equals_remapping(o))return true;
                rotateyr();
                for(int k=0;k<=3;k++){
                    if(equals_remapping(o))return true;
                    rotatezr();
                }
            }
        }
        return false;
    }
    inline void mirrorx(){
        for(int i=0;i<6;i++){
            faces[i].leftsideright();
        }
        swap(faces[left],faces[right]);
    }
    inline void mirrory(){
        faces[left].leftsideright();
        faces[right].leftsideright();
        faces[top].upsidedown();
        faces[bottom].upsidedown();
        faces[front].upsidedown();
        faces[back].upsidedown();
        swap(faces[front],faces[back]);
    }
    inline void mirrorz(){
        for(int i=0;i<6;i++){
            faces[i].upsidedown();
        }
        swap(faces[top],faces[bottom]);
    }
    inline bool operator== (cube o){
        for(int i=0;i<2;i++){
            for(int j=0;j<2;j++){
                for(int k=0;k<2;k++){
                    if(i)o.mirrorx();
                    if(j)o.mirrory();
                    if(k)o.mirrorz();
                    int res=false;
                    if(equals_rotate(o))res=true;
                    if(i)o.mirrorx();
                    if(j)o.mirrory();
                    if(k)o.mirrorz();
                    if(res)return true;
                }
            }
        }
        return false;
    }
    inline void input(){
        char ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[top].blocks[0][0]=ch-'0';ch=getchar();
        faces[top].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[top].blocks[1][0]=ch-'0';ch=getchar();
        faces[top].blocks[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[left].blocks[0][0]=ch-'0';ch=getchar();
        faces[left].blocks[0][1]=ch-'0';ch=getchar();
        faces[front].blocks[0][0]=ch-'0';ch=getchar();
        faces[front].blocks[0][1]=ch-'0';ch=getchar();
        faces[right].blocks[0][0]=ch-'0';ch=getchar();
        faces[right].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[left].blocks[1][0]=ch-'0';ch=getchar();
        faces[left].blocks[1][1]=ch-'0';ch=getchar();
        faces[front].blocks[1][0]=ch-'0';ch=getchar();
        faces[front].blocks[1][1]=ch-'0';ch=getchar();
        faces[right].blocks[1][0]=ch-'0';ch=getchar();
        faces[right].blocks[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[bottom].blocks[0][0]=ch-'0';ch=getchar();
        faces[bottom].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[bottom].blocks[1][0]=ch-'0';ch=getchar();
        faces[bottom].blocks[1][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[back].blocks[0][0]=ch-'0';ch=getchar();
        faces[back].blocks[0][1]=ch-'0';ch=getchar();
        while(ch<'0'||ch>'9')ch=getchar();
        faces[back].blocks[1][0]=ch-'0';ch=getchar();
        faces[back].blocks[1][1]=ch-'0';
    }
};
inline int read(){
    int x=0;int f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
int main(){
    int T;
    T=read();
    while(T--){
        s1=clock();
        cube a,b;
        a.input();
        b.input();
        if(a==b){
            printf("yes\n");
        }else{
            printf("no\n");
        }
    }
    for(int i=0;i<=T;i++){
        printf("yes\n");
    }
}

怎么样,你找出来错误了吗?

查看答案
第一段代码中	`C[2][i]=A[5][i];` 应是 `C[2][i]=A[0][i];`
		`C[4][0...3]=A[0][3..0]` 应是 `C[4][0..3]=A[5][3..0]`

第二段代码中	`faces[front]=faces[right];` 应是 `faces[front]=faces[left];`
		`faces[back]=faces[left];` 应是 `faces[back]=faces[right];`