zznu-2183: 口袋魔方
大致题意:
题目描述 口袋魔方又称为迷你魔方,通俗的来讲就是二阶魔方,只有八个角块的魔方,如图所示。
二阶魔方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: 口袋魔方的更多相关文章
- hdoj 2183 奇数阶魔方(II) 【模拟】+【法】
比赛的时候花了一个多小时,以做不做 分析:可观察:中间是(n*n+1)/2, 中间的上面是n*n,以下是1, 左边是n,右面是(n*n+1)-n,并且正对角线是最左上对到最右下端添加(+1).另外一条 ...
- css3之3D魔方动画(小白版)
在这里分享一下3D魔方动画,html5+CSS3即可完成~无图无真相,先上效果图 第一步非常简单,就是先将魔方的结构画出来.大家都玩过魔方,知道魔方是一个有六个面的正方体.这里我们先写一个大的di ...
- 魔方渗透系统安装VMtools教程
虚拟机魔方渗透系统安装VMtools教程 1.开机登陆后,如图点击安装VMtools. 2.进入media文件夹: cd /media 查看mdia文件夹内容: ls 3.打开VMware T ...
- 软媒魔方 v6.2.1.0 绿色纯净版及经典版
软媒魔方,最好用的 Windows 系统增强软件!从最早的优化大师发展为一款系统超级增强套装,自动化.智能化解决各种电脑问题.软媒魔方,全新一代Windows系统增强辅助工具,智能+专业双操控模式,系 ...
- 程设大作业xjb写——魔方复原
鸽了那么久总算期中过[爆]去[炸]了...该是时候写写大作业了 [总不能丢给他们不会写的来做吧 一.三阶魔方的几个基本定义 ↑就像这样,可以定义面的称呼:上U下D左L右R前F后B UD之间的叫E,LR ...
- EX的魔方
https://www.luogu.org/problem/show?pid=2007 题目背景 常神牛从来没接触过魔方,所以他要借助计算机来玩.即使是这样,他还是很菜. 题目描述 常神牛家的魔方都是 ...
- 用DirectX实现魔方(一)
关于魔方 魔方英文名字叫做Rubik's Cube,是由匈牙利建筑学教授和雕塑家Ernő Rubik于1974年发明,最初叫做Magic Cube(这大概也是中文名字的来历吧),1980年Ideal ...
- 用DirectX实现魔方(三)视角变换及缩放(附源码)
在本系列第一篇介绍过鼠标按键的功能,如下. 左键拖拽 - 旋转魔方 右键拖拽 - 变换视角 滚轮 - 缩放魔方 今天研究一下如何实现后面两个功能,用到的技术主要是Arcball,Arcball是实现M ...
- 用DirectX实现魔方(二)
这篇说一下如何构造魔方,主要包括魔方几何体的构造及纹理贴图.以下论述皆以三阶魔方为例,三阶魔方共有3 x 3 x 3 = 27个小立方体. 构造魔方 在第一篇里面说过,最初模型用的是微软的.x文件格式 ...
随机推荐
- Tomcat 目录结构
bin目录主要是用来存放tomcat的命令,主要有两大类,一类是以.sh结尾的(linux命令),另一类是以.bat结尾的(windows命令). 很多环境变量的设置都在此处,例如可以设置JDK路径. ...
- 【Qt开发】 QT:make: Nothing to be done for `first'和error:QtSql:No such file or directory
http://blog.csdn.NET/heqiuya/article/details/7774208 这是QT编程中常见的两个编译错误.可能你的代码在window下编译能正常通过,可是到到Linu ...
- 在java web 工程中实现登录和安全验证
登录验证代码 package security; import java.io.IOException; import javax.servlet.ServletException; import j ...
- 深入剖析Java虚拟机内存结构
深入剖析Java虚拟机内存模型 JVM整体架构 JVM整体架构如下: 通过编写代码来分析整个内存区域 public class Math { public static final Integer C ...
- 修改Ubuntu屏幕的分辨率
最近重新装了一下环境,用vnc连接服务器,发现分辨率过低,于是查了一下如何修改分辨率,将其调高. 编辑/etc/default/grub 搜索"#GRUB_GFXMODE=640x4 ...
- Guava 工具类之joiner的使用
joiner主要用于对字符串的连接,也可用于对map中key value的连接 public class JoinerTest { private static final List<Strin ...
- 记2017年年底,几次Python后端面试
1. 果壳 电话面试: 说一下TCP的三次握手,四次挥手,为什么会这样? http安全的性的了解,说一下对cookie和session的了解: 对mysql的了解,说一下你常用的数据类型,char和v ...
- MQ解决消息重发--做到幂等性
一.MQ消息发送 1.发送端MQ-client(消息生产者:Producer)将消息发送给MQ-server: 2.MQ-server将消息落地: 3.MQ-server回ACK给MQ-client( ...
- Laravel框架与ThinkPHP框架的不同
作为一个PHP菜鸟初学Laravel框架 在学习过程中我发现了其与TP框架的不同点,由于时间问题和认识还不够完善我先写出其中几点,有错误的地方希望各位大牛斧正... 1.渲染模版方式的不同:在Lara ...
- LeetCode 328——奇偶链表(JAVA)
给定一个单链表,把所有的奇数节点和偶数节点分别排在一起.请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性. 请尝试使用原地算法完成.你的算法的空间复杂度应为 O(1),时 ...