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

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. 6. MySQL 索引的数据结构(详细说明)

    6. MySQL 索引的数据结构(详细说明) @ 目录 6. MySQL 索引的数据结构(详细说明) 1. 为什么使用索引 2. 索引及其优缺点 2.1 索引概述 3. InnoDB中索引的推演 3. ...

  2. s = 0.5 * a * Math.pow(t,2),关于js动画,从一个公式说起

    s = 0.5 * a* t*t 上边这个是高中物理课本关于位移的计算公式,位移等于二分之一乘以a乘以t的平方,a是加速度,t是运动进行的时间(当然啦,初速度为0).下面我们会应用这个公式完成一个js ...

  3. 什么是单点登录?什么是SSO?什么是CAS?

    目录 单点登录简介 SSO&CAS是什么 单点登录适合什么场景 单点登录的三种实现方式 CAS的几个重要知识点 CAS的实现过程 单点登录简介 单点登录(SingleSignOn,SSO),就 ...

  4. 基于RK3568 + FPGA国产平台的多通道AD实时采集显示方案分享

    在工业控制与数据采集领域,高精度的AD采集和实时显示至关重要.今天,我们就来基于瑞芯微RK3568J + FPGA国产平台深入探讨以下,它是如何实现该功能的.适用开发环境如下: Windows开发环境 ...

  5. Electron 客户端开机自启动

    app.setLoginItemSettings 与 auto-launch 对比分析 一.稳定性对比 1. app.setLoginItemSettings 优点:作为Electron官方API,有 ...

  6. 【SpringCloud】OpenFeign服务接口调用

    OpenFeign服务接口调用 概述 我的理解: feign 为什么叫伪装? Feign可以把Rest的请求进行隐藏,伪装成类似SpringMVC的Controller一样.你不用再自己拼接url,拼 ...

  7. TMS WEB Core的DEMO

    TMS WEB Core的思路就是把你界面设计转换成js.这个打通了,将会使生产效率呈几何级数提高. 说如何让其demo的能跑起来: 1.看图.增加参数(TMSHttpConfig.exe). 2.运 ...

  8. datasnap的监督功能【2】-管理Session

    1.服务端的Session是有TDSSession定义的.TDSSession提供了许多有用的方法和特性,再开发室取得服务or重要信息. 如Session状态.安排Session独享定时or自动执行工 ...

  9. TdxpageControl融合窗口和free

    for I := cxpgcntrl1.PageCount - 1 downto 0do begin if cxpgcntrl1.Pages[i].Caption <> '首页' then ...

  10. 什么是 MCP,以及你为什么该关注它

    MCP 现在真的火起来了.现在已经有成千上万个 MCP "服务器",而且虽然是 Anthropic 发明的,就在几天前 OpenAI 也采纳了它.服务器就像 AI 的 " ...