欢迎您来我的网站看这篇题解!

Problem

有一个魔方可能被拧了不超过三次,同时还弄丢了一个角块上的两个贴纸。现在把这两个贴纸贴回去,请问有没有贴错?

只可能拧侧面,不会拧中间层,且每次只能拧 \(90^\circ\)。

魔方用一个 9 行 12 列的字符型矩阵表示:

初始魔方的展开图如下图:

\(1\le T\le 10\)

Solution

说实话没啥好考虑的,可能有取巧的方法?但是我不太想思考。

定义一个魔方类 Cube,包含了一个二维字符数组。只需要写六个成员函数(对应六种旋转操作),就可以描述这个魔方的所有旋转情况。

然后进行 dfs 搜索每一种可能的情况,并且与初始魔方展开图进行比较。

如果当前状态与展开图对比,不同的字符不超过两个,则说明复原成功。

  • 如果完全相同,则没有贴错,输出 No problem。
  • 如果有两个不相同,则贴错了,输出错误角块对应的三个数字。

没啥好多说的。Talk is cheap.Show me the code.

Code

/**************************************************************
* Problem:
* Author: Vanilla_chan
* Date:
* E-Mail: heshaohong2015@outlook.com
**************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<string>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#include<limits.h>
#define IL inline
#define re register
#define LL long long
#define ULL unsigned long long
#ifdef TH
#define debug printf("Now is %d\n",__LINE__);
#else
#define debug
#endif
#ifdef ONLINE_JUDGE
char buf[1<<23],* p1=buf,* p2=buf,obuf[1<<23],* O=obuf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
using namespace std; #define pii pair<int,int>
#define mk(a,b) make_pair(a,b)
/*
***111******
***111******
***111******
222333444555
222333444555
222333444555
***666******
***666******
***666******
*/ #define N 1000
struct Cube
{
string str[20];
Cube()
{
for(int i=0;i<20;i++) str[i]="!!!!!!!!!!!!!!!!";
str[0]="***111******";
str[1]="***111******";
str[2]="***111******";
str[3]="222333444555";
str[4]="222333444555";
str[5]="222333444555";
str[6]="***666******";
str[7]="***666******";
str[8]="***666******"; }
void output()
{
for(int i=0;i<9;i++) cout<<str[i]<<endl;
cout<<endl;
}
void top()
{
// debug
str[3]=str[3].substr(3,9)+str[3].substr(0,3);
string ss[20];
int mp[9][4]={1,4,1,5,1,5,1,6,1,6,2,6,2,6,3,6,3,6,3,5,3,5,3,4,3,4,2,4,2,4,1,4};
for(int i=0;i<9;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int t=0;t<2;t++)
{
// debug
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<8;k++)
{
// debug
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
}
}
}
void down()
{
str[5]=str[5].substr(3,9)+str[5].substr(0,3);
string ss[20];
int mp[9][4]={7,4,7,5,7,5,7,6,7,6,8,6,8,6,9,6,9,6,9,5,9,5,9,4,9,4,8,4,8,4,7,4};
for(int i=0;i<9;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int t=0;t<2;t++)
{
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<8;k++)
{
str[mp[k][0]][mp[k][1]]=ss[mp[k][2]][mp[k][3]];
}
}
}
void right()
{
string ss[20];
int mp[9][4]={4,7,4,8,4,8,4,9,4,9,5,9,5,9,6,9,6,9,6,8,6,8,6,7,6,7,5,7,5,7,4,7};
for(int i=0;i<9;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<9;i++) ss[i]=str[i];
for(int t=0;t<2;t++)
{
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<8;k++)
{
str[mp[k][0]][mp[k][1]]=ss[mp[k][2]][mp[k][3]];
}
} for(int i=11;i>=3;i--) str[i][5]=str[i-3][5]; int mp1[9][4]={4,10,3,6,5,10,2,6,6,10,1,6};
memcpy(mp,mp1,sizeof(mp));
for(int i=0;i<3;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<20;i++) ss[i]=str[i];
for(int k=0;k<3;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
} int mp2[9][4]={10,6,6,10,11,6,5,10,12,6,4,10};
memcpy(mp,mp2,sizeof(mp));
for(int i=0;i<3;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<20;i++) ss[i]=str[i];
for(int k=0;k<3;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
}
}
void left()
{
string ss[20];
int mp[9][4]={4,1,5,1,5,1,6,1,6,1,6,2,6,2,6,3,6,3,5,3,5,3,4,3,4,3,4,2,4,2,4,1};
for(int i=0;i<9;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<9;i++) ss[i]=str[i];
for(int t=0;t<2;t++)
{
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<8;k++)
{
str[mp[k][0]][mp[k][1]]=ss[mp[k][2]][mp[k][3]];
}
}
for(int i=11;i>=3;i--) str[i][3]=str[i-3][3]; int mp1[9][4]={4,12,3,4,5,12,2,4,6,12,1,4};
memcpy(mp,mp1,sizeof(mp));
for(int i=0;i<3;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<20;i++) ss[i]=str[i];
for(int k=0;k<3;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
} int mp2[9][4]={10,4,6,12,11,4,5,12,12,4,4,12};
memcpy(mp,mp2,sizeof(mp));
for(int i=0;i<3;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<20;i++) ss[i]=str[i];
for(int k=0;k<3;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
}
} void front()
{
string ss[20];
int mp[20][4]={4,4,5,4,5,4,6,4,6,4,6,5,6,5,6,6,6,6,5,6,5,6,4,6,4,6,4,5,4,5,4,4};
for(int i=0;i<8;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<9;i++) ss[i]=str[i];
for(int t=0;t<2;t++)
{
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<8;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
}
}
int mp1[30][4]={4,7,3,4,3,4,6,3,6,3,7,6,7,6,4,7,5,7,3,5,3,5,5,3,5,3,7,5,7,5,5,7,6,7,3,6,3,6,4,3,4,3,7,4,7,4,6,7};
memcpy(mp,mp1,sizeof(mp));
for(int i=0;i<12;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<9;i++) ss[i]=str[i];
for(int t=0;t<1;t++)
{
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<12;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
}
}
} void back()
{
string ss[20];
int mp[20][4]={4,10,5,10,5,10,6,10,6,10,6,11,6,11,6,12,6,12,5,12,5,12,4,12,4,12,4,11,4,11,4,10};
for(int i=0;i<8;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<9;i++) ss[i]=str[i];
for(int t=0;t<2;t++)
{
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<8;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
}
}
int mp1[20][4]={4,9,1,4,1,4,6,1,6,1,9,6,9,6,4,9,5,9,1,5,1,5,5,1,5,1,9,5,9,5,5,9,6,9,1,6,1,6,4,1,4,1,9,4,9,4,6,9};
memcpy(mp,mp1,sizeof(mp));
for(int i=0;i<12;i++) for(int j=0;j<4;j++) mp[i][j]--;
for(int i=0;i<9;i++) ss[i]=str[i];
for(int t=0;t<1;t++)
{
for(int i=0;i<9;i++) ss[i]=str[i];
for(int k=0;k<12;k++)
{
str[mp[k][2]][mp[k][3]]=ss[mp[k][0]][mp[k][1]];
}
}
} }; bool found=0; map<pii,string>out; void check(Cube cube)
{
Cube ans;
int diff=0;
pii pos;
for(int i=0;i<9;i++)
{
for(int j=0;j<12;j++)
{
if(cube.str[i][j]!=ans.str[i][j])
{
diff++;
pos=make_pair(i,j);
}
}
}
pos.first++;
pos.second++;
if(diff==0||diff==2)
{
found=1;
if(diff)
{
cout<<out[pos]<<endl;
}
else
{
cout<<"No problem"<<endl;
}
}
}
void dfs(int depth,Cube cube)
{
if(found) return;
check(cube);
if(found) return;
if(depth>=3) return;
Cube nxt; for(int i=0;i<=1;i++)
{
int t=i?1:3;
nxt=cube;
while(t--) nxt.front();
dfs(depth+1,nxt); t=i?1:3;
nxt=cube;
while(t--) nxt.back();
dfs(depth+1,nxt); t=i?1:3;
nxt=cube;
while(t--) nxt.left();
dfs(depth+1,nxt); t=i?1:3;
nxt=cube;
while(t--) nxt.right();
dfs(depth+1,nxt); t=i?1:3;
nxt=cube;
while(t--) nxt.top();
dfs(depth+1,nxt); t=i?1:3;
nxt=cube;
while(t--) nxt.down();
dfs(depth+1,nxt);
} } int main()
{
out[mk(4,3)]=out[mk(4,4)]=out[mk(3,4)]="1 2 3";
out[mk(1,4)]=out[mk(4,1)]=out[mk(4,12)]="1 2 5";
out[mk(1,6)]=out[mk(4,9)]=out[mk(4,10)]="1 4 5";
out[mk(3,6)]=out[mk(4,6)]=out[mk(4,7)]="1 3 4";
out[mk(6,1)]=out[mk(9,4)]=out[mk(6,12)]="2 5 6";
out[mk(6,3)]=out[mk(6,4)]=out[mk(7,4)]="2 3 6";
out[mk(6,6)]=out[mk(6,7)]=out[mk(7,6)]="3 4 6";
out[mk(9,6)]=out[mk(6,9)]=out[mk(6,10)]="4 5 6"; ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10); // Cube test;
// test.str[0]="***123******";
// while(1)
// {
// string cmd;cin>>cmd;
// if(cmd=="left") test.left();
// if(cmd=="right") test.right();
// if(cmd=="down") test.down();
// if(cmd=="top") test.top();
// if(cmd=="back") test.back();
// if(cmd=="front") test.front();
// test.output();
// } int t=1;
cin>>t;
while(t--)
{
found=0;
Cube cube;
for(int i=0;i<9;i++) cin>>cube.str[i];
dfs(0,cube); }
return 0;
}

2024杭电钉耙2-1003 HDOJ7447 绝对不模拟的简单魔方的更多相关文章

  1. 杭电ACM题单

    杭电acm题目分类版本1 1002 简单的大数 1003 DP经典问题,最大连续子段和 1004 简单题 1005 找规律(循环点) 1006 感觉有点BT的题,我到现在还没过 1007 经典问题,最 ...

  2. 杭电acm习题分类

    专注于C语言编程 C Programming Practice Problems (Programming Challenges) 杭电ACM题目分类 基础题:1000.1001.1004.1005. ...

  3. 杭电ACM分类

    杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...

  4. 杭电acm阶段之理工大版

    想參加全国软件设计大赛C/C++语言组的同学,假设前一篇<C和指针课后练习题总结>没看完的,请先看完而且依照上面的训练做完,然后做以下的训练. 传送门:http://blog.csdn.n ...

  5. 2018 Multi-University Training Contest 1 杭电多校第一场

    抱着可能杭电的多校1比牛客的多校1更恐怖的想法 看到三道签到题 幸福的都快哭出来了好吗 1001  Maximum Multiple(hdoj 6298) 链接:http://acm.hdu.edu. ...

  6. 2017杭电ACM集训队单人排位赛 - 6

    2017杭电ACM集训队单人排位赛 - 6 排名 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 59 1 X X 1 1 X X 0 1 ...

  7. acm入门 杭电1001题 有关溢出的考虑

    最近在尝试做acm试题,刚刚是1001题就把我困住了,这是题目: Problem Description In this problem, your task is to calculate SUM( ...

  8. 杭电acm 1002 大数模板(一)

    从杭电第一题开始A,发现做到1002就不会了,经过几天时间终于A出来了,顺便整理了一下关于大数的东西 其实这是刘汝佳老师在<算法竞赛 经典入门 第二版> 中所讲的模板,代码原封不动写上的, ...

  9. 杭电OJ——1198 Farm Irrigation (并查集)

    畅通工程 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可 ...

  10. 高手看了,感觉惨不忍睹——关于“【ACM】杭电ACM题一直WA求高手看看代码”

    按 被中科大软件学院二年级研究生 HCOONa 骂为“误人子弟”之后(见:<中科大的那位,敢更不要脸点么?> ),继续“误人子弟”. 问题: 题目:(感谢 王爱学志 网友对题目给出的翻译) ...

随机推荐

  1. Windows Api如何创建一个快捷方式并且在开始菜单搜索到自己的应用

    原文链接:http://cshelloworld.com/home/detail/1804473083243925504 当我们点击win10系统搜索框的时候,输入名称 ,win10会帮助我们匹配到对 ...

  2. 【数值计算方法】2&3维高斯积分的python实现

    目录 二维高斯积分 三维高斯积分 验证 本文只给出pythont实现和例题,数学推导见[数值计算方法]数值积分&微分-python实现 - FE-有限元鹰 - 博客园 二维高斯积分 pytho ...

  3. 【Python】转载一个python 爬虫的帖子

    原帖地址 原帖标题:爬取图网的4K图片自动保存本地 https://www.52pojie.cn/thread-1809600-1-1.html (出处: 吾爱破解论坛) python 代码 impo ...

  4. 痞子衡嵌入式:了解主从系统中i.MXRT系列MCU从主处理器接收App数据包超时机制

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是主从系统中i.MXRT系列MCU从主处理器接收App数据包超时机制. 在痞子衡旧文 <RT四位数Boot模式> 里的 1.2 ...

  5. go goroutine 怎样更好的进行错误处理

    前言 在 Go 语言程序开发中,goroutine 的使用是比较频繁的,因此在日常编码的时候 goroutine 里的错误处理,怎么做会比较好呢? 一般我们的业务代码如下: func main() { ...

  6. phpstorm、goland常用快捷键

    1) 文件操作相关的快捷键 快捷键 作用 Ctrl + E 打开最近浏览过的文件 Ctrl + N 快速打开某个 struct 结构体所在的文件 Ctrl + Shift + N 快速打开文件 Shi ...

  7. 解决ERROR 1231 (42000): Variable 'time_zone' can't

    MySQL根据配置文件会限制Server接受的数据包大小.有时候大的插入和更新会受 max_allowed_packet 参数限制,导致写入或者更新失败.(比方说导入数据库,数据表) mysql 数据 ...

  8. AAA认证

    AAA认证(Authentication, Authorization, and Accounting)是一个网络安全框架,用于管理用户如何访问网络资源.具体来说: 认证(Authentication ...

  9. vmware vsphere 6.5

    vmware vsphere 6.5是vsphere软件的经典版本,也是一款业界领先的服务器虚拟化平台,作为基础平台,是任何云计算环境的理想之选,其组件包括vCenter Server.ESXi.vS ...

  10. Netty源码—7.ByteBuf原理二

    大纲 9.Netty的内存规格 10.缓存数据结构 11.命中缓存的分配流程 12.Netty里有关内存分配的重要概念 13.Page级别的内存分配 14.SubPage级别的内存分配 15.Byte ...