一道算法面试题

阁楼上的伟哥 2010-05-26 12:24:41
有4个彩色的立方体。立方体的6个面,每面都涂上了1种颜色。一共有4种颜色,蓝色(B),红色(R),绿色(G)和黄色(Y)。立方体的6个面称为前(front)、后(back)、左(left)、右(right)、上(top)、下(bottom)。



这4个立方体的颜色排列为:

编号 front back left right top bottom

1 R B G Y B Y

2 R G G Y B B

3 Y B R G Y R

4 Y G B R R R



请将这4个立方体重叠摆放成为一个立柱,这个立柱有4个侧面,要求每个侧面都有4种颜色。

用你最拿手的语言编程实现,算出有多少种摆放方式。



...全文
2589 173 打赏 收藏 转发到动态 举报
写回复
用AI写文章
173 条回复
切换为时间正序
请发表友善的回复…
发表回复
AJ_Styles 2011-04-01
  • 打赏
  • 举报
回复
研究一下看看
renyaowu12 2011-03-17
  • 打赏
  • 举报
回复
这个貌似很复杂的样子诶!
merry_2 2011-03-17
  • 打赏
  • 举报
回复
再仔细想想
Wesley 2011-02-25
  • 打赏
  • 举报
回复
上班前自己乱想的,大家都是从六面体着手,不知道从颜色着手呢
为每个立方体建立4个一维数组,R[6],B[6],Y[6],G[6],6个元素分别代表立方体的6个面。以0.1代表,在所在面上是否有本色。
只是一个想法,没时间具体来进行计算,请各位大牛指教
枫叶红123 2011-01-11
  • 打赏
  • 举报
回复
想想看~~~
Michael_g 2011-01-10
  • 打赏
  • 举报
回复
我上面的代码是不包括当立柱总体(所有立方体一起旋转)的结果,如果算上总体旋转的结果那就是8个了,但这个结果在实际物体上是没有意义的,因为整体旋转不会影响四个立放体的排列方式,它只在数学排列上有意义。
我看了上面一些贴子,这个题是不能用数字的全排列来解决的,因为立方体的面与面的相对位置是不会改变的,如果是数字全排列那么六个面的排法应该有6*5*4*3*2*1 =720 和,显然不能是这样。
当我们从物体实际角度出发来看,一个立方体有六个面,两两相对,(当然面与面的相对位置是永远不会改变的^_^)如果每个面当一次“底面”,那么就有六种组合。任意一个面当“底面”时,我们可以水平旋转这个立方体,让每个“立面”当一次“前面”(“立面”有四个),则一共有 6*4种组合。按照这个思路我想大家都可以写出代码来,有时我们想问题要看清它的本质,这样就会比较好的解决问题 。
Michael_g 2011-01-09
  • 打赏
  • 举报
回复
不好意思看错了,我以为要每个面颜色一样呢,改一下CompareCube 函数代码就行了

共有 82944种组合,有两程符合要求。你可以把代码修改一下,就可以打印出这些组合了。

bool CompareCube(LPCUBE_UNION cube,int total/* 立方体的数量*/)
{
//分别对比“柱”的四个立面,是否含有全部颜色样
char color;
for (int i=0;i<4;i++)
{
color=0;
for (int ii=0;ii<total;ii++)
{
switch(cube[ii].color[i])
{
case 'Y':
color|=1;
break;
case 'R':
color|=2;
break;
case 'G':
color|=4;
break;
case 'B':
color|=8;
break;
}
}
if (color!=0xF) return false;
}
return true;
}
kbest 2011-01-09
  • 打赏
  • 举报
回复
啊啊啊,想着头大
Michael_g 2011-01-08
  • 打赏
  • 举报
回复
一共有82944种组合,但没有符合条件的组合方式。
Michael_g 2011-01-08
  • 打赏
  • 举报
回复
经过搜索,没有符合条件的组合。

/********** cube.h start ***********/
typedef struct{
char front; //z 轴面
char back; //z 轴面
char left; //x 轴面
char right; //x 轴面
char top; //y 轴面
char bottom; // y 轴面
}CUBE_STRUCT,*LPCUBE_STRUCT;

typedef union{
char color[7];
CUBE_STRUCT cube;
}CUBE_UNION,*LPCUBE_UNION;
typedef enum
{
UP=0,
DOWN,
LEFT,
RIGHT,
CW,
CCW
}ROTATION_DIRECTION;
//旋转立放体
void RotationCube(CUBE_STRUCT &cube,ROTATION_DIRECTION dir);
//搜索立方体的组合
void SearchCube(LPCUBE_UNION cube,int index,int total=4);
//比较立方体
bool CompareCube(LPCUBE_UNION cube,int total);

extern int Successfully,SearchCount;
/********* cube.h end***************/
/********* cube.cpp start****************/
int Successfully=0,SearchCount=0;
void RotationCube(CUBE_STRUCT &cube,ROTATION_DIRECTION dir /* 旋转方向*/)
{
char tmp;
switch (dir)
{
case UP://将立方体沿x轴向上旋转(左右面固定)
tmp = cube.bottom;
cube.bottom = cube.back;
cube.back = cube.top;
cube.top = cube.front;
cube.front = tmp;
break;
case DOWN://将立方体沿x轴向下旋转(左右面固定)
tmp = cube.bottom;
cube.bottom = cube.front;
cube.front = cube.top;
cube.top = cube.back;
cube.back = tmp;
break;
case LEFT://将立方体沿y轴向下旋转(上下面固定)
tmp = cube.front;
cube.front = cube.right;
cube.right = cube.back;
cube.back = cube.left;
cube.left = tmp;
break;
case RIGHT://将立方体沿y轴向下旋转(上下面固定)
tmp = cube.front;
cube.front = cube.left;
cube.left = cube.back;
cube.back = cube.right;
cube.right = tmp;
break;
case CW://将立方体沿z轴顺时针旋转(前后面固定)
tmp = cube.bottom;
cube.bottom = cube.right;
cube.right = cube.top;
cube.top = cube.left;
cube.left = tmp;
break;
case CCW://将立方体沿z轴逆时针旋转(前后面固定)
tmp = cube.bottom;
cube.bottom = cube.left;
cube.left = cube.top;
cube.top = cube.right;
cube.right = tmp;
break;
}
}
void SearchCube(LPCUBE_UNION cube,int index/* 当前立方体索引*/,int total/* 立方体的数量*/)
{
//以立方体的每个轴面为Y轴,然后绕Y轴旋转一周(四次),对比每次旋转后的颜色。
//因为立方体共有三个轴,加上每个轴可以上下颠倒,所以一共可以旋转 6*4=24次。
for (int i=0;i<6;i++)
{
if (i<=3)
{
//向上旋转立方体总共旋转四次
RotationCube(cube[index].cube,UP);
}
else if (i==4)
{
//顺时针旋转立方体一次
RotationCube(cube[index].cube,CW);
}
else
{
//顺时针旋转立方体两次
RotationCube(cube[index].cube,CW);
RotationCube(cube[index].cube,CW);
}

//如果这是第一个立方体,则不用进行左右旋转,从第二个立方体开始在进行左右旋转。
if (index==0 && total >1)
{
SearchCube(cube,index+1,total);
continue;
}

for (int ii=0;ii<4 ;ii++)
{
RotationCube(cube[index].cube,LEFT);
//如果这是最后一个立方体那么在此对比所有立方体的值。
if (index+1 == total)
{
SearchCount++;
if (CompareCube(cube,total))
{
Successfully++;
}
}
else
{
//不是最后一个立方体,旋转下一个立方体
SearchCube(cube,index+1,total);
}
}
}
RotationCube(cube[index].cube,CW);
}

bool CompareCube(LPCUBE_UNION cube,int total/* 立方体的数量*/)
{
//分别对比“柱”的四个立面,是否颜色一样
char color;
for (int i=0;i<4;i++)
{
color = cube[0].color[i];
for (int ii=1;ii<total;ii++)
{
if (color !=cube[ii].color[i])
return false;
}
}
return true;
}
/********* cube.cpp end****************/


#include <stdio.h>
#include <iostream>
#include "cube.h"

using namespace std;

int main(int argv,char* argc)
{

//初始化立面
CUBE_UNION cube[4] ={
{'R','B','G','Y','B','Y',0},
{'R','G','G','Y','B','B',0},
{'Y','B','R','G','Y','R',0},
{'Y','G','B','R','R','R',0}
};
char key;

SearchCube(cube,0);
cout << "Search Count:"<<SearchCount << " Successfully:" << Successfully;
cin >> key;
return 0;
}



leeang_ace 2011-01-06
  • 打赏
  • 举报
回复
主要的还是要找到一个很好的算法才行。
King_Bright 2010-12-30
  • 打赏
  • 举报
回复
我想到的: 因为只考虑侧面,且前后,左右,上下相对固定,所以只要每个正方体取两组,取出来的两组的值是交差的,也就是前后两面是不相邻的,上下左右当然也一样,这样可以穷举每一种可能,把值记录到三维数组进行判断
我试试看能不能写出代码
huang_63188 2010-12-17
  • 打赏
  • 举报
回复
我先顶10分下来
nxd395239299 2010-12-16
  • 打赏
  • 举报
回复

每一层如果不做旋转的话只有三种(三个对立面取其中两个作为前后左右)摆放方式:
首先固定第一层的立方体,有三种摆放方式.
其次固定第二层的立方体,立方体可以左右旋转,能旋转三次(四面),所以有3*4种摆放方式.
再次固定第三层的立方体,同上一层也有3*4种摆放方式.
最后固定第四层的立方体,也同上一层有3*4种摆放方式.

依次相乘就能得到所有的摆放方式,但是通过每一面都要有四种颜色的过滤条件,可以过滤调大部分的摆放方式.

最后每一种摆放方式又可以通过上下顺序的变化摆放出4*3*2*1种方式.

这样算到最后就能得到你的摆放方式.

我计算出来的是0.
风影萧诺 2010-10-26
  • 打赏
  • 举报
回复
我 想应该也是6中吧!
yuxingfirst 2010-10-26
  • 打赏
  • 举报
回复
我也不会,跟你一起坐等高人的答案
mazhai 2010-10-25
  • 打赏
  • 举报
回复
mark一下吧,大晚上的不想动脑子了。。。
martin913dc 2010-10-25
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 haoyizsw 的回复:]
为什么我算出来的是0
我是用二维数组穷举法的方法
应该是某步骤写漏了
[/Quote]二维数组的穷举法是不行的,这是个立方体,不可能随意搭配的
浅笑雪恨 2010-10-25
  • 打赏
  • 举报
回复
好难啊!我不知道
tmj5441302 2010-10-25
  • 打赏
  • 举报
回复
初步想法,先算出所有的排列数,然后减去有一个面中有两种一样眼色的数,不知道对不对
加载更多回复(153)

13,100

社区成员

发帖
与我相关
我的任务
社区描述
Java J2ME
社区管理员
  • J2ME社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧