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; }
相关文章推荐
- Nand flash 的发展和eMMC
- 08.Java 基础 - 反射
- java中instanceof的用法
- 校验用户输入的生日
- UESTC 2016 Summer Training #1 Div.2 E - Accepted Passwords 讨论
- HDU 1423 Greatest Common Increasing Subsequence LCIS
- 反引号backtick中输入多个命令
- ibatis配置xml文件中CDATA的用法
- 关于typedef的用法总结
- Android JNI 入门
- 算法导论(4) 顺序统计量
- nginx简介及安装
- Scala 循环语句
- View的滑动
- C++写时钟表
- 九九乘法表-javascrip循环结构
- extjs4.2点击树形菜单生成tab页并访问发送请求
- 基于图像分割的立体匹配方法
- 1045. Favorite Color Stripe (30)
- 其实你根本就懂闭包