魔方可以对它的6个面自由旋转。
我们来操作一个2阶魔方(如图1所示):
为了描述方便,我们为它建立了坐标系。
各个面的初始状态如下:
x轴正向:绿
x轴反向:蓝
y轴正向:红
y轴反向:橙
z轴正向:白
z轴反向:黄
假设我们规定,只能对该魔方进行3种操作。分别标记为:
x 表示在x轴正向做顺时针旋转
y 表示在y轴正向做顺时针旋转
z 表示在z轴正向做顺时针旋转
xyz 则表示顺序执行x,y,z 3个操作
题目的要求是:
用户从键盘输入一个串,表示操作序列。
程序输出:距离我们最近的那个小方块的3个面的颜色。
顺序是:x面,y面,z面。
例如:在初始状态,应该输出:
绿红白
初始状态下,如果用户输入:
x
则应该输出:
绿白橙
初始状态下,如果用户输入:
zyx
则应该输出:
红白绿
面的标号
模仿旋转示意图
问题简述:
模拟二阶魔方顺时针旋转
解题思路:
先把魔方6个面的颜色初始化为1~6(1到6的颜色具体其实可以自己定义),然后输入要模拟的字符串,对于沿x、y、z轴旋转这三个要模拟的过程分别写好对应的函数(其实3个函数的实现都是一样的啦),模拟完整个操作之后就输出最靠近你的那三个面的颜色(就是上图对着你的那个棱角的三个面,按x、y、z轴的顺序),输出颜色的话写了一个数字1~6所对应颜色的函数,这样就可以啦。
自己写的代码,还没来得及提交,如有错误欢迎指出
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int a[10][10]={0};
void toX(){
int x=a[2][0],y=a[2][1]; //注意:旋转一圈会把之前第一次那两个格子的颜色覆盖掉了 所以要先存起来 就和交换两个数道理一样
a[2][1]=a[4][3];
a[2][0]=a[4][1];
a[4][3]=a[6][2];
a[4][1]=a[6][3];
a[6][2]=a[5][0];
a[6][3]=a[5][2];
a[5][2]=x;
a[5][1]=y;
int c=a[1][0]; //刚开始也是忘了这个步骤 因为侧面也是要更新(模拟旋转魔方一个面的整个过程) 当然也是用交换的原理先存起来
a[1][0]=a[1][1];
a[1][1]=a[1][3];
a[1][3]=a[1][2];
a[1][2]=c;
}
void toY(){ //下面这两个函数实现的功能和toX()其实是一样的 翻转不同的面而已 这里就不再阐述了
int x=a[1][3],y=a[1][1];
a[1][3]=a[6][3];
a[1][1]=a[6][1];
a[6][3]=a[3][3];
a[6][1]=a[3][1];
a[3][3]=a[2][3];
a[3][1]=a[2][1];
a[2][3]=x;
a[2][1]=y;
int c=a[5][0];
a[5][0]=a[5][1];
a[5][1]=a[5][3];
a[5][3]=a[5][2];
a[5][2]=c;
}
void toZ(){
int x=a[1][2],y=a[1][3];
a[1][2]=a[5][2];
a[1][3]=a[5][3];
a[5][2]=a[3][1];
a[5][3]=a[3][0];
a[3][1]=a[4][2];
a[3][0]=a[4][3];
a[4][2]=x;
a[4][3]=y;
int c=a[2][0];
a[2][0]=a[2][1];
a[2][1]=a[2][3];
a[2][3]=a[2][2];
a[2][2]=c;
}
string yanse(int i){ //返回i对应的颜色
if(i==1)return "绿";
else if(i==2)return "白";
else if(i==3)return "蓝";
else if(i==4)return "橙";
else if(i==5)return "红";
else if(i==6)return "黄";
}
int main(){
for(int i=1;i<=6;i++){ //初始化颜色 //i分别对应上面yanse函数的值 (可理解为自己定义了一个数字到颜色的映射即 i-->颜色)
for(int j=0;j<4;j++){
a[i][j]=i;
}
}
char s[1000];
cin>>s;
int len=strlen(s);
for(int i=0;i<len;i++){
if(s[i]=='x')toX();
else if(s[i]=='y')toY();
else toZ();
}
cout<<yanse(a[1][3])<<yanse(a[5][2])<<yanse(a[2][1])<<"\n";
return 0;
}
学习简化后
思路:先按下图标号,然后把沿x、y、z轴旋转的数字变换写出来,例如沿x轴旋转:{{0,1,2,3},{4,21,14,19},{7,20,13,18}} 第一个表示 0->1, 1->2, 2->3, 3->0 数字的格子的变换,写个转换的函数,最后根据数字输出颜色就可以了
#include<iostream>
#include<cstring>
using namespace std;
int color[] = {1,1,1,1, 2,2,2,2, 3,3,3,3, 4,4,4,4, 5,5,5,5, 6,6,6,6};
void tran(int tran[][4]){
for(int i = 0; i < 3; i++){
int col = color[tran[i][0]];
color[tran[i][0]] = color[tran[i][3]];
color[tran[i][3]] = color[tran[i][2]];
color[tran[i][2]] = color[tran[i][1]];
color[tran[i][1]] = col;
}
}
void toColor(int i){
if(i == 1)cout << "绿";
if(i == 2)cout << "红";
if(i == 3)cout << "蓝";
if(i == 4)cout << "橙";
if(i == 5)cout << "白";
if(i == 6)cout << "黄";
}
int main(){
int tranx[][4] = {{0,1,2,3},{4,21,14,19},{7,20,13,18}};
int trany[][4] = {{4,5,6,7},{1,17,10,21},{2,18,8,22}};
int tranz[][4] = {{16,17,18,19},{0,12,8,4},{1,13,9,5}};
char op[1005];
cin >> op;
int len = strlen(op);
for(int i = 0; i < len; i++){
if(op[i] == 'x')tran(tranx);
else if(op[i] == 'y')tran(trany);
else tran(tranz);
}
toColor(color[1]);
toColor(color[4]);
toColor(color[18]);
return 0;
}