习题4-4 骰子涂色(Cube painting, UVa 253) 输入两个骰子,判断二者是否等价。每个骰子用6个字母表示,如图4-7所示。 图4-7 骰子涂色 例如rbgggr和rggbgr分别表示如图4-8所示的两个骰子。二者是等价的,因为图4-8(a) 所示的骰子沿着竖直轴旋转90°之后就可以得到图4-8(b)所示的骰子。
(a) (b) 图4-8 旋转前后的两个骰子 . Sample Input rbgggrrggbgr rrrbbbrrbbbr rbgrbgrrrrrg Sample Output TRUE FALSE FALSE
思路:暴力枚举,将一个骰子的所有姿态都列出来, 1、注意第一个图上的数字,那个是记录骰子面的顺序 2、先找最上面的,也就是1的位置,能排列6种(1,2,3,4,5,6) 3、然后找到了上面也就找到了与其相对的面,就是下面,就是字串中第六个元素。这个不会额外记录,因为有上就有下了。 4、然后就是中间四个的排列了,很显然,4种。 5、然后我们变换第二个骰子,看看它在这24种情况中,有没有一种的情况和第一个骰子的记录是相同的。(比较字串即可) 6、请注意骰子面的转换是否正确,虽然这个逻辑简单,但是容易写错,要好好检查,我就因为写错下标错了两次。
1#include<iostream> 2#include<string> 3using namespace std; 4/* 5 1 63 2 4 5 1在顶上 7 6 8 9 2 103 6 4 1 2在顶上 11 5 12 13 3 145 6 2 1 3在顶上 15 4 16 17 4 182 6 5 1 4在顶上 19 3 20 21 5 224 6 3 1 5在顶上 23 2 24 25 6 263 5 4 2 6在顶上 27 1 28 29 30*/ 31string s1,s2;//记录两个骰子的字符串 32int str_equal(string a,char s1,char s2,char s3,char s4,char s5,char s6)//比较两个字串相等吗 33{ 34 string b="0000000"; 35 b[1]=s1; 36 b[2]=s2; 37 b[3]=s3; 38 b[4]=s4; 39 b[5]=s5; 40 b[6]=s6; 41 //cout<<b.substr(1)<<endl; 42 if(a==b) 43 return 1; 44 return 0; 45} 46int exc(string a,char s1,char s2,char s3,char s4,char s5,char s6)//中间四个面的四种情况 47{ 48 if(str_equal(a,s1,s2,s3,s4,s5,s6)) return 1; 49 if(str_equal(a,s1,s3,s5,s2,s4,s6)) return 1; 50 if(str_equal(a,s1,s5,s4,s3,s2,s6)) return 1; 51 if(str_equal(a,s1,s4,s2,s5,s3,s6)) return 1; 52 return 0; 53} 54int main() 55{ 56 char c; 57 while(cin>>c) 58 { 59// cin>>s1; 60// s2=s1.substr(5); 61// s1.assign(s1,0,6); 62// cout<<s1<<" "<<s2<<endl; 63 //以上注释是一种输入方法,以下是另一种 64 65 s1=s2="0000000"; 66 s1[1]=c; 67 for(int i=2;i<=6;i++) //因为s1[1]已经在while中输入了 68 cin>>s1[i]; 69 for(int i=1;i<=6;i++) 70 cin>>s2[i]; 71 //cout<<s1.substr(1)<<" "<<s2<<endl; 72 73 if(exc(s1,s2[1],s2[2],s2[3],s2[4],s2[5],s2[6])){cout<<"TRUE"<<endl;continue;} 74 if(exc(s1,s2[2],s2[6],s2[3],s2[4],s2[1],s2[5])){cout<<"TRUE"<<endl;continue;} 75 if(exc(s1,s2[3],s2[6],s2[5],s2[2],s2[1],s2[4])){cout<<"TRUE"<<endl;continue;} 76 if(exc(s1,s2[4],s2[6],s2[2],s2[5],s2[1],s2[3])){cout<<"TRUE"<<endl;continue;} 77 if(exc(s1,s2[5],s2[6],s2[4],s2[3],s2[1],s2[2])){cout<<"TRUE"<<endl;continue;} 78 if(exc(s1,s2[6],s2[5],s2[3],s2[4],s2[2],s2[1])){cout<<"TRUE"<<endl;continue;} 79 80 cout<<"FALSE"<<endl; 81 82 } 83 return 0; 84} 85//AC at 2018/4/20 86
题外话:( 休战一个月后的第一道题,手生的很(才不),这道题的灵感还是来自蓝桥的直播课上老师演示的二阶魔方转换题(然而并并不会做) 因为最近一直看python,所以都不会用c++的string了,其中将字符连接起来就伤了我脑筋,不得已用了同样暴力的传进6+个参数的方法。(所谓一暴到底吗) 啊啊好想做后面的题,一直窝在第四章,会来不及看真正有用的算法的,本来以外蓝桥后算法会松一些,但是比赛还有(好事不是吗),我会继续努力的(乖孩子的话语,不喜欢) )
(a) (b) 图4-8 旋转前后的两个骰子 . Sample Input rbgggrrggbgr rrrbbbrrbbbr rbgrbgrrrrrg Sample Output TRUE FALSE FALSE