2024杭电钉耙2-1003 HDOJ7447 绝对不模拟的简单魔方
欢迎您来我的网站看这篇题解!
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 绝对不模拟的简单魔方的更多相关文章
- 杭电ACM题单
杭电acm题目分类版本1 1002 简单的大数 1003 DP经典问题,最大连续子段和 1004 简单题 1005 找规律(循环点) 1006 感觉有点BT的题,我到现在还没过 1007 经典问题,最 ...
- 杭电acm习题分类
专注于C语言编程 C Programming Practice Problems (Programming Challenges) 杭电ACM题目分类 基础题:1000.1001.1004.1005. ...
- 杭电ACM分类
杭电ACM分类: 1001 整数求和 水题1002 C语言实验题——两个数比较 水题1003 1.2.3.4.5... 简单题1004 渊子赛马 排序+贪心的方法归并1005 Hero In Maze ...
- 杭电acm阶段之理工大版
想參加全国软件设计大赛C/C++语言组的同学,假设前一篇<C和指针课后练习题总结>没看完的,请先看完而且依照上面的训练做完,然后做以下的训练. 传送门:http://blog.csdn.n ...
- 2018 Multi-University Training Contest 1 杭电多校第一场
抱着可能杭电的多校1比牛客的多校1更恐怖的想法 看到三道签到题 幸福的都快哭出来了好吗 1001 Maximum Multiple(hdoj 6298) 链接:http://acm.hdu.edu. ...
- 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 ...
- acm入门 杭电1001题 有关溢出的考虑
最近在尝试做acm试题,刚刚是1001题就把我困住了,这是题目: Problem Description In this problem, your task is to calculate SUM( ...
- 杭电acm 1002 大数模板(一)
从杭电第一题开始A,发现做到1002就不会了,经过几天时间终于A出来了,顺便整理了一下关于大数的东西 其实这是刘汝佳老师在<算法竞赛 经典入门 第二版> 中所讲的模板,代码原封不动写上的, ...
- 杭电OJ——1198 Farm Irrigation (并查集)
畅通工程 Problem Description 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府"畅通工程"的目标是使全省任何两个城镇间都可 ...
- 高手看了,感觉惨不忍睹——关于“【ACM】杭电ACM题一直WA求高手看看代码”
按 被中科大软件学院二年级研究生 HCOONa 骂为“误人子弟”之后(见:<中科大的那位,敢更不要脸点么?> ),继续“误人子弟”. 问题: 题目:(感谢 王爱学志 网友对题目给出的翻译) ...
随机推荐
- 130道基础OJ编程题之: 68~77
130道基础OJ编程题之: 68~77 @ 目录 130道基础OJ编程题之: 68~77 68:BC72 平均身高 69:BC74 HTTP状态码 70:BC75 数字三角形 71:BC76 公务员面 ...
- 针对N=p^rq分解之初探
针对N=p^r*q分解之初探 论文地址:https://eprint.iacr.org/2015/399.pdf 题目:https://www.nssctf.cn/problem/2016 from ...
- 稳定且高性价比的大模型存储:携程 10PB 级 JuiceFS 工程实践
在过去两年多的时间里,随着 AI 大模型的快速发展,JuiceFS 在携程内部得到了越来越多 AI 用户的关注.目前,携程通过 JuiceFS 管理着 10PB 数据规模,为 AI 训练等多个场景提供 ...
- Qt 获取本机ipv4地址
Qt 获取本机本地网卡的IPv4地址 本文介绍怎么用Qt去获取本机的ipv4地址 文章目录 Qt 获取本机本地网卡的IPv4地址 用法 用法 话不多说,直接上代码: QHostAddress host ...
- vue2中如何使用组合式API和vueuse工具包
vue2中如何使用组合式API和vueuse工具包 1. 安装 @vue/composition-api 依赖包 yarn add @vue/composition-api # 或 npm insta ...
- 「2024 年度技术精华盘点」IvorySQL & PostgreSQL 技术干货全解析!
2024 年,IvorySQL 公众号持续输出高质量技术内容,涵盖 PostgreSQL 核心技术解析 和 IvorySQL 创新实践 两大方向.无论您是数据库领域的初学者,还是经验丰富的开发者,这些 ...
- kubernetes 容器编排系统
前言 docker解决了打包和隔离的问题,但是在docker集群中我们需要解决更多的问题,如调度(容器在哪运行).生命周期及健康状况(确保容器在无错的情况下运行).服务发现(容器所处位置,和容器通信) ...
- iis 固定回收问题
项目背景:站点有一个计算业务场景,耗时较久. 偶发性发生:进度条过程中,发生卡死.日志没有然后记录. 查看windows 事件,问题时间 有was 自动回收 当前站点 ,如下图 后设置 ...
- 【网络攻防】ARP欺骗实验
实验概述 ARP欺骗是一类地址欺骗类病毒,属于木马病毒,自身不具备主动传播的特性,不会自我复制.但是由于其发作的时候会不断向全网发送伪造的ARP数据包,导致网络无法正常运行,严重的甚至可能带来整个网络 ...
- 【Unity3D】把相机视角放置到编辑器当前位置视角
[Unity3D]把相机视角放置到编辑器当前位置视角 零.问题 Unity开发过程中,经常要将相机调整值对应位置,但是通过数值来调有时候不怎么方便,有什么方法可以快速让相机的视角与编辑器当前视角同步呢 ...