您的位置:首页 > 其它

HDU 5250 三阶魔方(很有意思的模拟题)

2016-07-12 21:00 429 查看


三阶魔方

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 123 Accepted Submission(s): 57



Problem Description

给定三阶魔方的基本操作:



现给出一个由基本操作组合成的操作序列,求问:对一个初状态(六个面都是拼好的)的魔方进行多少次连续的序列操作后,魔方会恢复到初状态。

Input

第一行为T,表示输入数据组数。

下面T行,每行给出一个合法的操作序列字符串,每行不超过100个字符。

Output

对第i组数据,输出

Case #i:

然后输出一个整数,表示答案。若魔方不会恢复则输出-1。

Sample Input

3
R2
R'R'U2
RU


Sample Output

Case #1:
2
Case #2:
6
Case #3:
105


Source

2015年百度之星程序设计大赛
- 初赛(1)

Recommend

hujie

题意:

给定一个操作序列,问执行多少次操作以后,魔方会恢复原状,如果不能则输出-1

思路:

很明显对于同一个操作执行多次肯定是可以还原的。
考虑魔方上的某一个面的一个点(标号为1),如果执行一次操作以后还在原来的位置,那么不管执行几次都在原来的位置。
如果不在原来的位置,例如1到了2的位置,2到了6的位置,6到了1的位置,那么执行三次操作以后就可以复原这三个点(相当于转了一圈)。

具体的做法是,我们可以执行一遍这个操作,找出所有的环,求出所有环长度的最小公倍数即可(想一想是不是很有道理呢)

为了简化编码,我们可以把U2变成UU,U‘变成UUU,这样只要编写6种操作就可以了。

怎么执行操作呢,每一个操作我们都要记录魔方当前的状态,如果使用3x3x3的坐标记录点的位置,那么将无法保存颜色信息(在哪一面),因此可以用3x3x6的数组保存6个面,在执行一个操作时(例如R),会涉及到5个面,即右,上、后、下、前,R顺时针旋转90度,其他的面每个只有3个数字会改变

代码写的比较长,个人感觉这样直观一些

#include <bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
const int INF=0x3f3f3f3f;
const int maxn=3e3+50;
const int Mod=1e9+7;
typedef long long ll;

using namespace std;

const int W=3;
int maze[6][W][W];

int hashId[100];
bool vis[100];

string get(char c,char t)
{
string ret="";
if (t=='2') return ret+c+c;
if (t=='\'') return ret+c+c+c;
}
string expandCommand(string &s)
{

string ret="";
int sz=s.size();
for (int i=0;i<sz;){
if(i==sz-1 || (isalpha(s[i]) && isalpha(s[i+1]))) {
ret+=s[i];
i++;
}
else {
ret+=get(s[i],s[i+1]);
i+=2;
}
}
return ret;
}

//0 1 2 3 4 5
//U D L R F B
void rotateClockwise(int face[W][W])
{
int tmp[W][W];
for (int i=0;i<W;i++)
for(int j=0;j<W;j++){
tmp[i][j]=face[W-j-1][i];
}
for (int i=0;i<W;i++){
for(int j=0;j<W;j++){
//   printf("%d ",tmp[i][j]);
face[i][j]=tmp[i][j];
}
// puts("");
}
}

void swapClockwise( int &s1,int &s2,int &s3,
int &s4,int &s5,int &s6,
int &s7,int &s8,int &s9,
int &s10,int &s11,int &s12){
int tmp[13];
tmp[1]=s1; tmp[2]=s2; tmp[3]=s3;
tmp[4]=s4; tmp[5]=s5; tmp[6]=s6;
tmp[7]=s7; tmp[8]=s8; tmp[9]=s9;
tmp[10]=s10; tmp[11]=s11; tmp[12]=s12;

s1=tmp[10]; s2=tmp[11]; s3=tmp[12];
s4=tmp[1]; s5=tmp[2]; s6=tmp[3];
s7=tmp[4]; s8=tmp[5]; s9=tmp[6];
s10=tmp[7]; s11=tmp[8]; s12=tmp[9];
}

inline int getR(int x){
x--;
return x/3;
}
inline int getC(int x){
x--;
return x%3;
}
void excute(string &s)
{

int cnt=1;
for (int i=0;i<6;i++){
for(int j=0;j<W;j++)
for (int k=0;k<W;k++)
maze[i][j][k]=cnt++;
}
int sz=s.size();
for (int i=0;i<sz;i++){
//   printf("%d %c\n",i,s[i]);
if (s[i]=='U'){
//0 1 2 3 4 5
//U D L R F B

rotateClockwise(maze[0]);
swapClockwise(
maze[5][getR(3)][getC(3)],
maze[5][getR(2)][getC(2)],
maze[5][getR(1)][getC(1)],

maze[3][getR(3)][getC(3)],
maze[3][getR(2)][getC(2)],
maze[3][getR(1)][getC(1)],

maze[4][getR(3)][getC(3)],
maze[4][getR(2)][getC(2)],
maze[4][getR(1)][getC(1)],

maze[2][getR(3)][getC(3)],
maze[2][getR(2)][getC(2)],
maze[2][getR(1)][getC(1)]

);
}else if (s[i]=='D'){
//0 1 2 3 4 5
//U D L R F B
rotateClockwise(maze[1]);
swapClockwise(
maze[4][getR(7)][getC(7)],
maze[4][getR(8)][getC(8)],
maze[4][getR(9)][getC(9)],

maze[3][getR(7)][getC(7)],
maze[3][getR(8)][getC(8)],
maze[3][getR(9)][getC(9)],

maze[5][getR(7)][getC(7)],
maze[5][getR(8)][getC(8)],
maze[5][getR(9)][getC(9)],

maze[2][getR(7)][getC(7)],
maze[2][getR(8)][getC(8)],
maze[2][getR(9)][getC(9)]
);
}else if (s[i]=='L'){
//0 1 2 3 4 5
//U D L R F B
rotateClockwise(maze[2]);
swapClockwise(
maze[0][getR(1)][getC(1)],
maze[0][getR(4)][getC(4)],
maze[0][getR(7)][getC(7)],

maze[4][getR(1)][getC(1)],
maze[4][getR(4)][getC(4)],
maze[4][getR(7)][getC(7)],

maze[1][getR(1)][getC(1)],
maze[1][getR(4)][getC(4)],
maze[1][getR(7)][getC(7)],

maze[5][getR(9)][getC(9)],
maze[5][getR(6)][getC(6)],
maze[5][getR(3)][getC(3)]
);

}else if (s[i]=='R'){
//0 1 2 3 4 5
//U D L R F B
rotateClockwise(maze[3]);
swapClockwise(
maze[0][getR(9)][getC(9)],
maze[0][getR(6)][getC(6)],
maze[0][getR(3)][getC(3)],

maze[5][getR(1)][getC(1)],
maze[5][getR(4)][getC(4)],
maze[5][getR(7)][getC(7)],

maze[1][getR(9)][getC(9)],
maze[1][getR(6)][getC(6)],
maze[1][getR(3)][getC(3)],

maze[4][getR(9)][getC(9)],
maze[4][getR(6)][getC(6)],
maze[4][getR(3)][getC(3)]
);
}else if (s[i]=='F'){
//0 1 2 3 4 5
//U D L R F B
rotateClockwise(maze[4]);
swapClockwise(
maze[0][getR(7)][getC(7)],
maze[0][getR(8)][getC(8)],
maze[0][getR(9)][getC(9)],

maze[3][getR(1)][getC(1)],
maze[3][getR(4)][getC(4)],
maze[3][getR(7)][getC(7)],

maze[1][getR(3)][getC(3)],
maze[1][getR(2)][getC(2)],
maze[1][getR(1)][getC(1)],

maze[2][getR(9)][getC(9)],
maze[2][getR(6)][getC(6)],
maze[2][getR(3)][getC(3)]
);
}else if (s[i]=='B'){
//0 1 2 3 4 5
//U D L R F B
rotateClockwise(maze[5]);
swapClockwise(
maze[0][getR(3)][getC(3)],
maze[0][getR(2)][getC(2)],
maze[0][getR(1)][getC(1)],

maze[2][getR(1)][getC(1)],
maze[2][getR(4)][getC(4)],
maze[2][getR(7)][getC(7)],

maze[1][getR(7)][getC(7)],
maze[1][getR(8)][getC(8)],
maze[1][getR(9)][getC(9)],

maze[3][getR(9)][getC(9)],
maze[3][getR(6)][getC(6)],
maze[3][getR(3)][getC(3)]
);
}
}
return;
}

void getHash(){
int cnt=1;
for (int i=0;i<6;i++){
for(int j=0;j<W;j++)
for (int k=0;k<W;k++){
hashId[cnt++]=maze[i][j][k];
//  printf("%d %d\n",cnt-1,hashId[cnt-1]);
}
}
}

ll gcd(ll a,ll b){
return (b==0)? a:gcd(b,a%b);
}

int getCycle(vector<int> &v){
mem(vis,0);
for (int i=1;i<=36;i++){
if (vis[i]) continue;
int cnt=1,pos=i;
vis[pos]=1;
while(hashId[pos]!=i){
// printf("pos:%d hashId:%d %d\n",pos,hashId[pos],i);
//   getchar();
pos=hashId[pos];
vis[pos]=1;
cnt++;
}
//   cout<<cnt<<'\n';
v.push_back(cnt);
}
}

ll LCM(vector<int> &v){
ll ret=1;
int sz=v.size();
for (int i=0;i<sz;i++){
ret=ret/gcd(ret,(ll)v[i])*v[i];
}
return ret;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n,T;
string str;
scanf("%d",&T);
for (int cs=1;cs<=T;cs++){
printf("Case #%d:\n",cs);
cin>>str;
string command=expandCommand(str);
// cout<<command<<'\n';
excute(command);
getHash();
vector<int> cycle;
getCycle(cycle);
printf("%lld\n",LCM(cycle));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: