华师一附中OI组
标题:
UVA253 cube painting 讨论
[打印本页]
作者:
admin
时间:
2017-9-27 12:54
标题:
UVA253 cube painting 讨论
题目描述很简单,给定两个骰子,每个骰子用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;
}
复制代码
作者:
admin
时间:
2017-9-27 12:57
这个代码很精妙,第5行的数组是旋转后的位置对应关系。和第20行的代码共同实现固定某个面朝上的一种情况;第23行的循环是水平旋转4次。其他的代码就不一一细说了。
作者:
admin
时间:
2018-6-3 11:40
钱鹏宇大牛的做法:
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int i,j,c[3][2]={{0,5},{1,4},{2,3}};
char a[13],b[13];
scanf("%s%s",a,b);
for(int k=0;k<3;k++)
{
int n=c[k][0],m=c[k][1];
if((a[n]==b[n]||a[n]==b[m])&&(a[m]==b[n]||a[m]==b[m]))
{
continue;
}
else
{
printf("NO!");
return 0;
}
}
printf("YES!");
return 0;
}
复制代码
作者:
吴语林
时间:
2018-6-27 16:00
#include <algorithm>
#include <iostream>
#include <cmath>
#include <cstring>
#include <map>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cstdio>
#include <cstdlib>
using namespace std;
char a[100];
int ha1[1000][1000],ha2[1000][1000],i;
int main()
{
while(~scanf("%s",a))
{
memset(ha1,0,sizeof(ha1));memset(ha2,0,sizeof(ha2));
for(i=0;i<=5;i++)
ha1[a[i]][a[5-i]]++,ha1[a[5-i]][a[i]]++;
for(i=0;i<=5;i++)
ha2[a[i+6]][a[11-i]]++,ha2[a[11-i]][a[i+6]]++;
for(i=0;i<=2;i++)
if(ha1[a[i]][a[5-i]]!=ha2[a[i]][a[5-i]])
break;
if(i==3) printf("TRUE\n");
else printf("FALSE\n");
}
return 0;
}
复制代码
作者:
admin
时间:
2018-6-27 23:11
楼上吴同学这个做法能解释一下吗
欢迎光临 华师一附中OI组 (http://hsyit.cn/)
Powered by Discuz! X3.2