大致题意:

题目描述

口袋魔方又称为迷你魔方,通俗的来讲就是二阶魔方,只有八个角块的魔方,如图所示。
二阶魔方8个角块的位置均可进行任意互换(!种状态),如果以一个角块不动作为参考角块,其他7个
角块都能任意转换方向(即37种状态)。如果在空间中旋转则不计算方向不同而状态相同的魔方,实际上的准确
状态数还应除以24。所以二阶魔方的总状态数为: !*^=。二阶魔方的最远复原距离(即最需要最多
步骤复原的状态)为11次全旋转,或者14次普通旋转,此结果可以用暴力穷举算法计算出
下面给你一个口袋魔方,只需要进行一些简单的处理就能解决这道题了。对于此魔方的任意一个面,你可以选择
顺时针旋转或者逆时针进行一次90度的旋转,如果能够进行不超过一次的旋转操作,就能使此魔方复原(每面内
部颜色相同,共六种颜色),那么请输出“我真是个小机灵鬼!”,否则请输出“这个魔方有bug!”。 输入 第一行一个T,代表测试实例数。
每个测试实例有6行输入。
每行4个整数,代表相应位置的颜色
输入数字位置对应下面魔方展开图。
如a代表输入的第一个整数所在位置,其他同上。
+ - + - + - + - + - + - +
| q | r | a | b | u | v |
+ - + - + - + - + - + - +
| s | t | c | d | w | x |
+ - + - + - + - + - + - +
| e | f |
+ - + - +
| g | h |
+ - + - +
| i | j |
+ - + - +
| k | l |
+ - + - +
| m | n |
+ - + - +
| o | p |
+ - + - + 输出 如题。
样例输入 样例输出 我真是个小机灵鬼!
我真是个小机灵鬼!
我真是个小机灵鬼!
这个魔方有bug!

(已折叠! )

大致思路:

1.枚举全部地旋转方法,共八种: 顺时针 : 横一层/横二层/竖一层/竖二层 / 侧一层/侧二层

同时逆时针,全部都对应一个;共16种!

2. 每次旋转,只转动一层的八个格点而已 ; 八个格点只需要顺序或者逆序排序一下然后赋值即可!

3.每旋转一次, 每个面上相邻的两个不用考虑顺序,因为这两个毕竟顺着方向上的旋转下是绑定在一起的!

4/繁琐的东西用函数实现, 把一个大问题化解成小问题!

5/注意把他们展开后,记得画图!用线顺时针在平面图上用线顺时针连起来! 后面的那个格子上下是颠倒的!串线的时候需要注意三维空间的真实情况!!

题解:

 #include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define N 50008
#define ll long long
#define mem(a,x) memset(a,x,sizeof(a)) ///问题 C: 签到(sign)
int a[]; //存每个面的颜色
int mp1[][]={
{,,,},
{,,,},
{,,,},
{,,,},
{,,,},
{,,,}
};
int mp2[][]={
{,,,,,,,}, //y=1&2
{,,,,,,,},
{,,,,,,,}, //rotate(),x=1&x=2
{,,,,,,,},
{,,,,,,,},
{,,,,,,,}
}; void Rotate(int k,int mode){ //转动第k行mp2[]的列表 ,mode=0顺,mode=1表示逆
vector<int>ans;
for(int i=;i<;i++){
int x=mp2[k][i];
ans.push_back(a[x]);
} if(mode==){
ans.push_back(ans[]);
ans.push_back(ans[]);
ans.erase(ans.begin(),ans.begin()+); for(int i=;i<;i++){
int x=mp2[k][i];
a[x]=ans[i];
}
}
else{
int x=ans[],y=ans[];
ans.insert(ans.begin(),x);
ans.insert(ans.begin(),y);
ans.erase(ans.end()-,ans.end());
for(int i=;i<;i++){
int x=mp2[k][i];
a[x]=ans[i];
}
}
}
bool judge(){
for(int i=;i<;i++){
int mx=-,minn=inf;
for(int j=;j<;j++){
int x=mp1[i][j];
mx=max(mx,a[x]);
minn=min(minn,a[x]);
}
if(mx!=minn)return ;
}
return ;
}
//void debug(){
// printf("%3d %3d %3d %3d %3d %3d\n",a[17],a[18],a[1],a[2],a[21],a[22]);
// printf("%3d %3d %3d %3d %3d %3d\n",a[19],a[20],a[3],a[4],a[23],a[24]);
// printf(" %3d %3d\n %3d %3d\n",a[5],a[6],a[7],a[8]);
// printf(" %3d %3d\n %3d %3d\n",a[9],a[10],a[11],a[12]);
// printf(" %3d %3d\n %3d %3d\n",a[13],a[14],a[15],a[16]);
// printf("________\n");
//}
void debug(){
cout<<endl;
for(int i=;i<=;i++)
printf("%d%c",a[i],i%==?'\n':' ');
cout<<endl;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
a[]=-;
for(int i=;i<=;i++)
scanf("%d",&a[i]); // bool f=0;
// for(int i=0;!f&&i<6;i++) //mode=0
// {
// Rotate(i,0);
// if(judge()==1)f=1;debug();
// Rotate(i,1);
// Rotate(i,1);
// if(judge()==1)f=1;debug();
// Rotate(i,0);
// // if(judge()==0)printf("i1=%d,66666666\n",i);
// } if(judge()==){
printf("我真是个小机灵鬼!\n");
}
else{
bool f=;
for(int i=;!f&&i<;i++) //mode=0
{
Rotate(i,);
if(judge()==)f=;
Rotate(i,);
// if(judge()==0)printf("i1=%d,66666666\n",i);
}
for(int i=;!f&&i<;i++) //mode=1
{
Rotate(i,);
if(judge()==)f=;
Rotate(i,);
// if(judge()==0)printf("i1=%d,66666666\n",i);
}
if(!f)
printf("这个魔方有bug!\n");
else
printf("我真是个小机灵鬼!\n");
}
} return ;
}

(简洁思路版!)

当然,我第一次不是这么写的!我是把所有的16种情况,每种情况单写一个函数解决的!

写到第8个时,发现正着和逆着旋转某个角度其实可以化简,就回头看看,加了个op=-1!

题解:(写了六个小时!!)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define N 110
char str[N]; ///第一维表示魔方的面
int mp[][]=
{
{,,, ,,, ,,, ,,}, ///总共六个面,下标0-5 face_id
{,,, ,,, ,,, ,,},
{,,, ,,, ,,, ,,},
{,,, ,,, ,,, ,,},
{,,, ,,, ,,, ,,},
{,,, ,,, ,,, ,,}
}; struct node{
int x,y,z,Face;
node(int x=,int y=,int z=,int Face=):x(x),y(y),z(z),Face(Face){}
}; int a[][][][]; ///四维对应 x-y-z- face_id bool judge() ///判断是否达成魔方的要求
{
for(int i=; i<=; i++) //总共六个面
{
int minn=,maxx=-;
for(int j=; j<=; j++)
{
int x=mp[i][j*-];
int y=mp[i][j*-];
int z=mp[i][j*-];
minn=min(minn, a[x][y][z][i]);
maxx=max(maxx, a[x][y][z][i]);
}
if(minn!=maxx)return false;
}
return true;
}
void debug(vector<int>st,int mode){
cout<<"_______________***"<<"mode="<<mode<<endl;
for(int i=; i<=; i++) //总共六个面
{
for(int j=; j<=; j++)
{
int x=mp[i][j*-];
int y=mp[i][j*-];
int z=mp[i][j*-];
cout<<a[x][y][z][i]<<" "; ///四维对应 x-y-z- face_id
}
cout<<endl;
} cout<<"***"<<"st_list__"<<endl;
for(int i=;i<(int)st.size();i++){
if((i+)%==)
printf(" %d **\n",st[i]);
else
printf(" %d",st[i]);
}
cout<<endl;
}
void rotating(int mode){ vector<int>st;
int op=;
if(mode==||mode==){
for(int i=; i<=; i++) //总共六个面
{
for(int j=; j<=; j+=)
{
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
}
int len=st.size(),cnt=; if(mode==)op=-;
for(int i=; i<=; i++) //总共4个面,只取两个即可
{
for(int j=; j<=; j+=)
{
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ; ///x=1的四块,shun/ni时针
cnt++;
}
}
} else if(mode == || mode==){
for(int i=; i<=; i++){ //总共4个面
for(int j=; j<=; j+=){
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
}
int len=st.size(),cnt=; if(mode==)op=-;
for(int i=; i<=; i++){ //总共4个面,只取两个即可
for(int j=; j<=; j+=){
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///x=2的四块,shun/ni时针
cnt++;
}
}
}
else if(mode==||mode==){
int ii[]={,,,};
for(int k=; k<=; k++){ //总共4个面
if(ii[k]==){
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
continue;
}
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
}
int len=st.size(),cnt=; if(mode==)op=-;
for(int k=; k<=; k++){ //总共4个面,只取两个即可
if(ii[k]==){
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt+*op+len)%len] ;
cnt++;
}
continue;
}
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt+*op+len)%len] ;///y=1的四块,shun/ni时针
cnt++;
}
}
} else if(mode==||mode==){ ///y=2, 3,4,1,2
int ii[]={,,,};
for(int k=; k<=; k++){ //总共4个面
if(ii[k]==){
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
continue;
}
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
}
int len=st.size(),cnt=; if(mode==)op=-;
for(int k=; k<=; k++){ //总共4个面,只取两个即可
if(ii[k]==){
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt+*op+len)%len] ;
cnt++;
}
continue;
}
for(int j=; j<=; j++){
int i=ii[k];
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt+*op+len)%len] ;///y=2的四块,shun/ni时针
cnt++;
}
} }
else if(mode==||mode==){ if(mode==) op=-;
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
} int len=st.size(),cnt=;
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=1的四块,shun/逆时针
cnt++;
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=1的四块,shun/逆时针
cnt++;
}
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=1的四块,shun/逆时针
cnt++;
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=1的四块,shun/逆时针
cnt++;
}
}
else if(mode==||mode==){ if(mode==)op=-;
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
st.push_back(a[x][y][z][i]);
} int len=st.size(),cnt=;
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=2的四块,shun/逆时针
cnt++;
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=2的四块,shun/逆时针
cnt++;
}
for(int j=; j<=; j++){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=2的四块,shun/逆时针
cnt++;
}
for(int j=; j<=; j+=){
int i=;
int x=mp[i][j*-];int y=mp[i][j*-];int z=mp[i][j*-];
a[x][y][z][i] = st[(cnt-*op+len)%len] ;///z=2的四块,shun/逆时针
cnt++;
} } // debug(st,mode);
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
for(int i=; i<=; i++) //总共六个面
{
for(int j=; j<=; j++)
{
int x=mp[i][j*-];
int y=mp[i][j*-];
int z=mp[i][j*-];
cin>>a[x][y][z][i]; ///四维对应 x-y-z- face_id
}
}
// vector<int>st;
// debug(st,-1); if(judge()==true)
{
printf("我真是个小机灵鬼!\n");
}
else
{
bool ans=false; for(int i=;i<&&!ans;i++)
{
rotating(i);
ans=judge();
rotating(i^); //旋转回去
}
if(ans)
printf("我真是个小机灵鬼!\n");
else
printf("这个魔方有bug!\n");
}
} return ;
} // for(int i=0;i<=11;i++){
// int test=i;
// rotating(test);rotating(test^1);rotating(test^1);rotating(test);
// ///test成功:0,1,2, 3,4,5,6,7,8,9 ,
// if(judge()==true)
// {
// printf("Test %d OK!\n",test);
// }
// else{
// printf("%d False!\n",test);
// }
// continue;
// }
//rotating(0);rotating(0^1); //测试成功
//rotating(2);rotating(3); ///测试成功
// rotating(4);rotating(4^1); ///测试成功
// rotating(6);rotating(6^1); ///测试成功
// rotating(10);rotating(10^1); ///测试成功 ,对一个正确的解,同一个层面顺拧一次、反拧一次必定正确 // rotating(2^1);
// cout<<"^1= "<<(2^1)<<endl;

zznu-2183: 口袋魔方的更多相关文章

  1. hdoj 2183 奇数阶魔方(II) 【模拟】+【法】

    比赛的时候花了一个多小时,以做不做 分析:可观察:中间是(n*n+1)/2, 中间的上面是n*n,以下是1, 左边是n,右面是(n*n+1)-n,并且正对角线是最左上对到最右下端添加(+1).另外一条 ...

  2. css3之3D魔方动画(小白版)

      在这里分享一下3D魔方动画,html5+CSS3即可完成~无图无真相,先上效果图 第一步非常简单,就是先将魔方的结构画出来.大家都玩过魔方,知道魔方是一个有六个面的正方体.这里我们先写一个大的di ...

  3. 魔方渗透系统安装VMtools教程

    虚拟机魔方渗透系统安装VMtools教程 1.开机登陆后,如图点击安装VMtools. 2.进入media文件夹: cd /media   查看mdia文件夹内容: ls   3.打开VMware T ...

  4. 软媒魔方 v6.2.1.0 绿色纯净版及经典版

    软媒魔方,最好用的 Windows 系统增强软件!从最早的优化大师发展为一款系统超级增强套装,自动化.智能化解决各种电脑问题.软媒魔方,全新一代Windows系统增强辅助工具,智能+专业双操控模式,系 ...

  5. 程设大作业xjb写——魔方复原

    鸽了那么久总算期中过[爆]去[炸]了...该是时候写写大作业了 [总不能丢给他们不会写的来做吧 一.三阶魔方的几个基本定义 ↑就像这样,可以定义面的称呼:上U下D左L右R前F后B UD之间的叫E,LR ...

  6. EX的魔方

    https://www.luogu.org/problem/show?pid=2007 题目背景 常神牛从来没接触过魔方,所以他要借助计算机来玩.即使是这样,他还是很菜. 题目描述 常神牛家的魔方都是 ...

  7. 用DirectX实现魔方(一)

    关于魔方 魔方英文名字叫做Rubik's Cube,是由匈牙利建筑学教授和雕塑家Ernő Rubik于1974年发明,最初叫做Magic Cube(这大概也是中文名字的来历吧),1980年Ideal ...

  8. 用DirectX实现魔方(三)视角变换及缩放(附源码)

    在本系列第一篇介绍过鼠标按键的功能,如下. 左键拖拽 - 旋转魔方 右键拖拽 - 变换视角 滚轮 - 缩放魔方 今天研究一下如何实现后面两个功能,用到的技术主要是Arcball,Arcball是实现M ...

  9. 用DirectX实现魔方(二)

    这篇说一下如何构造魔方,主要包括魔方几何体的构造及纹理贴图.以下论述皆以三阶魔方为例,三阶魔方共有3 x 3 x 3 = 27个小立方体. 构造魔方 在第一篇里面说过,最初模型用的是微软的.x文件格式 ...

随机推荐

  1. Python随笔日记(1)

    Python学习 1.安装python .之后在Windows中配置环境变量(计算机\属性\高级系统设置\环境变量\系统变量\path后加入 :路径) 2.注意变量的命名的规则 字母.数字.下划线 p ...

  2. 攻防世界CRYPTO新手练习

    0x01 base64 直接base64 Decode 得到flag cyberpeace{Welcome_to_new_World!} 0x02 Caesar key为12 的恺撒密码,解密德fla ...

  3. VS编译错误._CRT_SECURE_NO_WARNINGS、_WINSOCK_DEPRECATED_NO_WARNINGS

    1.不记得原来的情况了,记得大概是这样: 低版本的 VC编译器 使用 strcpy.sprintf 等它不会报错,但是 高版本的 VS编译就会报错,大意是 strcpy.sprintf 等函数 不安全 ...

  4. edusoho 查找网址对应的控制器和模板页面

    刚接触这套系统的新手都在纠结模板在哪个文件里,有时候就算告诉他,遇到其他同样的模板照样还问,授人以鱼不如授人以渔!这个文章记录下我自己的看法,大爪子忽喷! 刚看到群里有人问 xxx.com/admin ...

  5. redis的发布和订阅操作

  6. 洛谷 题解 P1220 【关路灯 】

    搜索 传参 inline void DFS(int now,int l,int r,int cnt,int sum,int k) /* now为当前点 l为左端点 r为右端点 cnt为当前耗电量 su ...

  7. python xlrd模块

    一.什么是xlrd模块? Python操作excel主要用到xlrd和xlwt这两个库,即xlrd是读excel,xlwt是写excel的库. 二.使用介绍 1.常用单元格中的数据类型 类型 含义 e ...

  8. hadoop 》》 django 简单操作hdfs 语句

    >> from django.shortcuts import render # Create your views here. from hdfs.client import Clien ...

  9. not or and 的优先级是不同的

    not or and 的优先级是不同的: not > and > or 请用最快速度说出答案: not 1 or 0 and 1 or 3 and 4 or 5 and 6 or 7 an ...

  10. 用python打开文件夹的三种方式

    一.利用explorer.exe import os # 利用explorer.exe执行 start_directory = r'C:\代码\软件包' os.system("explore ...