【蓝桥杯】历届真题 魔方旋转问题(高职组) Java

问题描述

  魔方可以对它的6个面自由旋转。

  我们来操作一个2阶魔方,如图:

         

  为了描述方便,我们为它建立了坐标系。

  各个面的初始状态如下:
  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个面上的所有颜色。但苦于自己的空间想象能力略差,于是借助iPad上的笔记软件来进行绘图。但还是不够直观,怎么办呢?我想:干脆把它直接化为展开图来看,岂不是更直观?于是借助着展开图使用暴力方法将此题解开。

因我的图过于丑陋且使用文字表示颜色,并不直观。借用同站创作者同篇博客的展开图作为展示。

        

        原文链接:蓝桥杯:魔方旋转问题【高职组】_Cod_ing的博客-CSDN博客

代码

import java.util.Scanner;

public class Main{
	public static void main(String[] args){
		Scanner sc = new Scanner(System.in);
		String str = sc.next();
		int[][] moFang = {
			{1,1,1,1}, //x轴正向
			{2,2,2,2}, //x轴反向
			{3,3,3,3}, //y轴正向
			{4,4,4,4}, //y轴反向
			{5,5,5,5}, //z轴正向
			{6,6,6,6}  //z轴反向
		};
		for(int i=0; i<str.length(); i++){
			char c = str.charAt(i);

			if(c=='x'){
				int[] s1 = new int [2];
				int[] s2 = new int [2];
				//y正-z反
				s1[0] = moFang[5][0];
				s1[1] = moFang[5][1];			
				moFang[5][0] = moFang[2][2];
				moFang[5][1] = moFang[2][0];	
				//z反-y反
				s2[0] = moFang[3][1];
				s2[1] = moFang[3][3];			
				moFang[3][1] = s1[0];
				moFang[3][3] = s1[1];				
				//y反-z正
				s1[0] = moFang[4][2];
				s1[1] = moFang[4][3];			
				moFang[4][3]=s2[0];
				moFang[4][2]=s2[1];	
				//z正-y正
				moFang[2][0]=s1[0];
				moFang[2][2]=s1[1];
				//x全对
			} else if(c=='y'){
				int[] s1 = new int [2];
				int[] s2 = new int [2];
				//z正-x反
				s1[0] = moFang[1][1];
				s1[1] = moFang[1][3];
				moFang[1][1] = moFang[4][3];
				moFang[1][3] = moFang[4][1];	
				//x反-z反
				s2[0] = moFang[5][1];
				s2[1] = moFang[5][3];
				moFang[5][1] = s1[0];
				moFang[5][3] = s1[1];
				//z反-x正
				s1[0]=moFang[0][1];
				s1[1]=moFang[0][3];
				moFang[0][1] = s2[0];
				moFang[0][3] = s2[1];
				//x正-z正
				moFang[4][1] = s1[0];
				moFang[4][3] = s1[1];
			} else if(c=='z'){
				int[] s1 = new int [2];
				int[] s2 = new int [2];
				//x正-y反
				s1[0] = moFang[3][0];
				s1[1] = moFang[3][1];
				moFang[3][0] = moFang[0][0];
				moFang[3][1] = moFang[0][1];
				//y反-x反
				s2[0] = moFang[1][0];
				s2[1] = moFang[1][1];
				moFang[1][0] = s1[0];
				moFang[1][1] = s1[1];
				//x反-y正
				s1[0] = moFang[2][0];
				s1[1] = moFang[2][1];
				moFang[2][0] = s2[0];
				moFang[2][1] = s2[1];
				//y正-x正
				moFang[0][0] = s1[0];
				moFang[0][1] = s1[1];
			}
		}
		String color = ""+moFang[0][1]+moFang[2][0]+moFang[4][3];
		for(int i=0; i<color.length(); i++){
			char color_a = color.charAt(i);
			if(color_a == '1'){
				System.out.print("绿");
			} else if(color_a == '2'){
				System.out.print("蓝");
			} else if(color_a == '3'){
				System.out.print("红");
			} else if(color_a == '4'){
				System.out.print("橙");
			} else if(color_a == '5'){
				System.out.print("白");
			} else if(color_a == '6'){
				System.out.print("黄");
			}
		}
	}
}

        此代码在思维量上并没有多大的难度,关键就是在于心细!心细!心细!初看这道题时觉得蛮简单,没想到光是数x y z这些变换让我跟它磕了两个多小时。

总结

        值得一提的是,我在自己编译器的测试用例下都可以通过,且答案正确。但无法在蓝桥杯的OJ上通过。100多行的代码我反复看了三四遍仍未发现问题所在。

        在我寻找别人的解决方案时,发现同站的小伙伴也出现了和我一样的问题。

        链接: 试题 历届真题 魔方旋转问题(Java)_地_方的博客-CSDN博客

        并且在别站的早期代码同样是无法通过的状态,而我和它代码的结果是一致的,让我不得不怀疑是否网站OJ本身的测试用例出现了问题。

         链接:算法笔记_233:二阶魔方旋转(Java) - 舞动的心 - 博客园 (cnblogs.com)

        这大概是目前对于该题最全面的解读了,有兴趣的朋友们可以自己去试试这道题,并不难,只是较为繁琐。希望能解答你的部分疑惑,如果能帮到你,我很开心。如果有大佬使用Java将该题在OJ上通过,希望可以在评论区指点一二,万分感谢。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值