|
题目描述很简单,给定两个骰子,每个骰子用6个字符表示每个面的颜色,问这两个骰子是不是同一个。原题:https://uva.onlinejudge.org/inde ... problem&problem=189
这类题目在NOI系列赛场上偶有所见,北京1999有个五骰子问题,给出五个摞在一起的骰子的11个面,问是否可能这样;ctsc1999也有一个罗杰游戏,子程序也是骰子的翻转,对于此类题目,数学建模最重要。我是这样做的:
如原题图中所示:假设标准的骰子最上面的面是1,正前方是2,左边是3,右边是4,后面是5,下面是6的话,记作 123456 。若把2旋转到1的位置,只需要在竖直平面旋转一格,则可能是263415,就是是说2在原来1的位置,6在原来2的位置,3在原来3的位置****,我们表示为2,6,3,4,1,5,当然还可以有其他的,比如2,3,1,6,4,5,和刚才不同时水平面也旋转了一下。所以我们若将一个骰子固定,另外的一个骰子的每个面都先对应到第一个面,然后水平旋转90度。若有一个情况和地一个骰子相等就认为是同一个。
每个骰子最多24个变化,计算量不大就不考虑优化了。
代码如下:- #include <iostream>
- using namespace std;
- string s,s1,s2;
- int i;
- int m[6][6]={ {1,2,3,4,5,6},
- {2,6,3,4,1,5},
- {3,2,6,1,5,4},
- {4,2,1,6,5,3},
- {5,1,3,4,6,2},
- {6,5,3,4,2,1} };
- bool can(string s1,string s2)
- {
- string t;
- char ch;
- int i,j,k;
- for( i=1;i<=6;i++)
- {
- t="";
- for( j=1;j<=6;j++) t=t+s1[m[i-1][j-1]-1];
- ///cout<<t<<endl;
- for( k=1;k<=4;k++)
- {
- ch=t[1];
- t[1]=t[2];
- t[2]=t[4];
- t[4]=t[3];
- t[3]=ch;
- ///cout<<t<<endl;
- if(s2==t) return 1;
- }
- }
- return 0;
- }
- int main()
- {
- while(cin>>s)
- {
- s1=s2="";
- for (i=0;i<=5;i++) s1=s1+s[i];
- for (i=6;i<=11;i++) s2=s2+s[i];
- if(can(s1,s2)) cout<<"TRUE"<<endl;
- else cout<<"FALSE"<<endl;
- }
- return 0;
- }
复制代码
|
|