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文件格式 ...
随机推荐
- windows下exfat无法写入怎么修复?
为了能够实现mac与windows文件共享,把移动硬盘格式化为exfat了,可是在osx中放入文件后,在windows上紧进行读取写入时出现错误,提示使用chkdsk进行修正,下面是修正步骤. 方法/ ...
- Hackergame2019 web
前几天跟着几个大佬一起看了看中科大的Hackergame2019,这个比赛主要针对的是新手,激发新生对CTF比赛的兴趣,虽然我已经大三了,但实在是因为我过于five,也只能帮大佬打打杂,这里把自己做的 ...
- 【miscellaneous】语音识别工具箱综述和产品介绍
原文:http://www.thinkface.cn/thread-893-1-1.html 今天是周末,想来想去,还是写一篇这样的博文吧.算是对语音识别这一段时间的总结,为后来的人融入铺好前面的路. ...
- 最新 4399java校招面经 (含整理过的面试题大全)
从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.4399等10家互联网公司的校招Offer,因为某些自身原因最终选择了4399.6.7月主要是做系统复习.项目复盘.Leet ...
- 使用socket.io实现双向实时消息传递,(客服聊天功能)
思否 https://segmentfault.com/a/1190000010974426 博客园 https://www.cnblogs.com/limitcode/p/7845168.html ...
- [Cometoj#3 B]棋盘_状压dp
棋盘 题目链接:https://cometoj.com/contest/38/problem/B?problem_id=1535 数据范围:略. 题解: 因为行数特别小,所以$dp$的时候可以状压起来 ...
- PTA(Advanced Level)1050.String Subtraction
Given two strings S1 and S2, S=S1−S2 is defined to be the remaining string after taking all the char ...
- Oracle表级约束和列级约束
Oracle表级约束和列级约束 1. 表级定义约束 指的是在定义完一个表所有列之后,再去定义所有相关的约束. 注意:not null 约束只能在列级上定义. 2. 列级定义约束 指的是在定义一个表的每 ...
- 分布式session一致性问题
1.分布式session一致性 :指服务器集群情况下session共享的问题. 2.session的作用:保存服务器(tomcat)与客户端(浏览器)整个通讯的会话基本信息. 3.session应用场 ...
- C++反汇编第一讲,不同作用域下的构造和析构的识别
目录大纲: 1.全局(静态)对象的识别,(全局静态全局一样的,都是编译期间检查,所以当做全局对象看即可.) 1.1 探究本质,理解构造和析构的生成,以及调用方式(重要,如果不想知道,可以看总结.) 2 ...