青岛模拟B题:全场卡到死的一个题

题目中给的是一个二阶魔方,然后每个面上的颜色用数字来表示


题目需要判断:用最多一次旋转,是否能够将魔方复原?


首先要知道有6种情况可以旋转一次之后复原

根据题目的输入顺序:分别是:顶面,正面,底面,下面,左面,右面

也就是说:

1和3不动,逆时针或者顺时针

2和4不动,逆时针或者顺时针

5和6不动,逆时针或者顺时针


这个是别人家的代码:感谢我柠檬巨:

感谢我柠檬


然后我SB的考虑怎么拿魔方:也是旋转

但是把整个面的旋转都考虑进去

1和3不动的时候,是2536的旋转

2和4不动的时候,是1536的旋转

5和6不动的时候,是1234的旋转

所以写成了这个样子:


#include<bits/stdc++.h>
using namespace std;

int a[10][10],T;

void debug(){
    for(int i=1;i<=6;i++)
        for(int j=1;j<=4;j++)
            printf("%d%c",a[i][j],j==4?'\n':' ');
    puts("");
}

void L(){
    int ch;
    ch=a[1][2];a[1][2]=a[2][2];a[2][2]=a[3][2];a[3][2]=a[4][2];a[4][2]=ch;
    ch=a[1][4];a[1][4]=a[2][4];a[2][4]=a[3][4];a[3][4]=a[4][4];a[4][4]=ch;
    ch=a[6][1];a[6][1]=a[6][3];a[6][3]=a[6][4];a[6][4]=a[6][2];a[6][2]=ch;
}

void R(){
    int ch;
    ch=a[1][2];a[1][2]=a[4][2];a[4][2]=a[3][2];a[3][2]=a[2][2];a[2][2]=ch;
    ch=a[1][4];a[1][4]=a[4][4];a[4][4]=a[3][4];a[3][4]=a[2][4];a[2][4]=ch;
    ch=a[6][1];a[6][1]=a[6][2];a[6][2]=a[6][4];a[6][4]=a[6][3];a[6][3]=ch;
}

void c1(){
    //1234
    int ch[10];
    for(int i=1;i<=4;i++) ch[i]=a[1][i];
    for(int i=1;i<=4;i++) a[1][i]=a[2][i];
    for(int i=1;i<=4;i++) a[2][i]=a[3][i];
    for(int i=1;i<=4;i++) a[3][i]=a[4][i];
    for(int i=1;i<=4;i++) a[4][i]=ch[i];
    ch[0]=a[5][1];a[5][1]=a[5][2];a[5][2]=a[5][4];a[5][4]=a[5][3];a[5][3]=ch[0];
    ch[0]=a[6][1];a[6][1]=a[6][3];a[6][3]=a[6][4];a[6][4]=a[6][2];a[6][2]=ch[0];
}

void c2(){
    //1536
    int ch[10];
    for(int i=1;i<=4;i++) ch[i]=a[1][i];
    for(int i=1;i<=4;i++) a[1][i]=a[5][i];
    a[5][1]=a[3][4];a[5][2]=a[3][3];a[5][3]=a[3][2];a[5][4]=a[3][1];
    a[3][4]=a[6][1];a[3][3]=a[6][2];a[3][2]=a[6][3];a[3][1]=a[6][4];
    for(int i=1;i<=4;i++) a[6][i]=ch[i];
    ch[0]=a[4][1];a[4][1]=a[4][2];a[4][2]=a[4][4];a[4][4]=a[4][3];a[4][3]=ch[0];
    ch[0]=a[2][1];a[2][1]=a[2][3];a[2][3]=a[2][4];a[2][4]=a[2][2];a[2][2]=ch[0];
}

void c3(){
    //2546
    int ch[10];
    for(int i=1;i<=4;i++) ch[i]=a[2][i];
    a[2][1]=a[5][2];a[2][2]=a[5][4];a[2][3]=a[5][1];a[2][4]=a[5][3];
    a[5][2]=a[4][4];a[5][4]=a[4][3];a[5][1]=a[4][2];a[5][3]=a[4][1];
    a[4][4]=a[6][3];a[4][3]=a[6][1];a[4][2]=a[6][4];a[4][1]=a[6][2];
    a[6][3]=ch[1];a[6][1]=ch[2];a[6][4]=ch[3];a[6][2]=ch[4];
    ch[0]=a[1][1];a[1][1]=a[1][2];a[1][2]=a[1][4];a[1][4]=a[1][3];a[1][3]=ch[0];
    ch[0]=a[3][1];a[3][1]=a[3][3];a[3][3]=a[3][4];a[3][4]=a[3][2];a[3][2]=ch[0];
}

bool ok(){
    for(int i=1;i<=6;i++)
        for(int j=2;j<=4;j++)
            if (a[i][j]!=a[i][1]) return false;
    return true;
}
/*
bool check(){
    if (ok()) return true;
    for(int i=1;i<=4;i++){
        c1();
        for(int j=1;j<=4;j++){
            c2();
            for(int k=1;k<=4;k++){
                c3();
                L();
                if (ok()) return true;
                R();
                R();
                if (ok()) return true;
                L();
            }
        }
    }
    return false;
}
*/

bool check(){
    if (ok()) return true;
    L();
    if (ok()) return true;
    R();R();
    if (ok()) return true;
    L();

    c2();
    if (ok()) return true;
    L();
    if (ok()) return true;
    R();R();
    if (ok()) return true;
    L();

    c3();
    if (ok()) return true;
    L();
    if (ok()) return true;
    R();R();
    if (ok()) return true;
    L();
    return false;
}

int main(){
    //freopen("input.txt","r",stdin);
    //freopen("output.txt","w",stdout);
    scanf("%d",&T);
    while(T--){
        for(int i=1;i<=6;i++)
            for(int j=1;j<=4;j++)
                scanf("%d",&a[i][j]);
        if (check())
            puts("YES");
        else
            puts("NO");
    }
    return 0;
}


然后,总结下大家为什么会各种wa:

因为为了偷懒,没有这个:


这个跟空间想象力其实没有太多关系

因为全是转移的细节,一定要折出来一个看看它是怎么转的